• 《Linux高性能服务器编程》--高级I/O函数


    目录

    1--Pipe()

    2--dup() 和 dup2()

    3--readv() 和 writev()

    4--sendfile()

    5--mmap() 和 munmap()

    6--spice()

    7--tea()

    8--fcntl()


    1--Pipe()

    1. #include
    2. int pipe(int fd[2]);
    3. // 成功返回0,失败返回-1

            pipe() 函数可用于创建一个管道,以实现线程间通信;

            fd[0] 和 fd[1] 分别构成管道的两端,fd[0] 只能用于从管道读出数据,fd[1] 只能用于往管道写入数据;因此要实现双向数据传输,必须使用两个管道;

            fd[0] 和 fd[1] 是阻塞的,当读取空管道时,会阻塞直到有数据,同理当写入满管道时,会阻塞直到管道有空间(默认管道容量为 65536 字节);

            如果写端 fd[1] 的引用计数减少至 0,即没有线程往管道写入数据时,读取 fd[0] 将返回 0,即读到 EOF;如果读端 fd[0] 的引用计数减少至 0,即没有任何进程从管道读取数据时,写入 fd[1] 将失败,并引发 SIGPIPE 信号;

    1. #include
    2. #include
    3. int socketpair(int domain, int type, int protocol, int fd[2]);
    4. // 创建双向管道,成功时返回0,失败时返回-1,fd[0]和fd[1]可读可写;

    2--dup() 和 dup2()

    1. #include
    2. // 类似于复制 file_descriptor
    3. int dup(int file_descriptor);
    4. // 类似于复制 descriptor_one,返回的fd >= file_descriptor_two
    5. int dup2(int file_descriptor_one, int file_descriptor_two);

            dup() 和 dup2() 用于创建一个新的文件描述符,新文件描述符和原有文件描述符指向相同的文件、管道或网络连接;

    3--readv() 和 writev()

    1. #include
    2. // 分散读,可能会读多次,返回读取的字节数
    3. ssize_t readv(int fd, const struct iovec* vector, int count);
    4. // 集中写,返回写入的字节数
    5. ssize_t writev(int fd, const struct iovec* vector, int count);

    4--sendfile()

    1. #include
    2. ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count);
    3. // 成功返回传输的字节数,失败返回 -1

            sendfile() 在两个文件描述符之间直接传递数据(完全在内核中操作),完全避免了内核缓冲区和用户缓冲区之间的数据拷贝,被称为零拷贝

            in_fd 表示待读出内容的文件描述符,其必须指向真实的文件,不能是管道和 socket;out_fd 必须是一个 socket

    5--mmap() 和 munmap()

    1. #include
    2. void* mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
    3. int munmap(void *start, size_t length);

            mmap() 用于申请一段内存空间,其可作为进程间通信的共享内存,也可以将文件直接映射到内存空间中;munmap() 用于释放由 mmap 创建的内存空间;

    6--spice()

    1. #include
    2. ssize_t splice(int fd_in, loff_t* off_in, int fd_out, loff_t* off_out, size_t len, unsigned int flags);

            splice() 用于在两个文件描述符之间移动数据(零拷贝);

            fd_in 和 fd_out 必须至少有一个是管道文件描述符;

    7--tea()

    1. #include
    2. ssize_t tee(int fd_in, int fd_out, size_t len, unsigned int flags);

            tea() 用于在两个管道文件描述符之间复制数据(零拷贝);tea() 不消耗数据(复制),因此源文件描述符的数据仍保留;

    8--fcntl()

    1. #include
    2. int fcntl(int fd, int cmd, ...);

            fcntl() 提供了对文件描述符的各种控制操作;

  • 相关阅读:
    Linux进程/线程几个经典问题
    springboot+Vue+ElementUI 教资考前指导网站系统
    OSMNX 路网数据下载分析Python包
    使用.NET源生成器(SG)实现一个自动注入的生成器
    centos7在线安装rabbitmq及其远程连接
    软考系列(系统架构师)- 2011年系统架构师软考案例分析考点
    Harmony 复杂图形自绘制
    Linux内核链表
    包装类-Wrapper
    数字物业管理成趋势,传统物业公司如何通过转型实现数字化蝶变?
  • 原文地址:https://blog.csdn.net/weixin_43863869/article/details/132994239