zoukankan      html  css  js  c++  java
  • Linux高性能服务器编程:高级I/O函数

    用于创建文件描述符的函数:pipe, dup, dup2

    用于读写数据的函数:readv, writev, sendfile, mmap, munmap, splice, tee

    用于控制I/O行为和属性的函数:fcntl

    1.pipe函数

    int pipe(int fd[2]);

    pipe函数可用于创建一个管道,以实现进程间通信。

    通过pipe函数创建的这两个文件描述符fd[0]和fd[1]分别构成管道的两端,往fd[1]写入的数据可以从fd[0]读出。

    并且fd[0]只能用于从管道中读出数据,fd[1]从管道中写入数据。默认两个文件描述符都是阻塞的。

    应用程序能往一个TCP连接中写入多少字节的数据,取决于对方的接收窗口的大小和本端的拥塞窗口的大小。而管道本身拥有一个容量限制,

    规定了如果应用程序不将数据从管道读走的话,该管道最多能被写入多少字节的数据。默认大小为65536字节。

    int socketpair(int domain, int type, int protocol, int fd[2]); //创建双向管道。

    2. dup函数和dup2函数

    int dup(int file_descriptor);

    int dup2(int file_descriptor_one, int file_descriptor_two);

    dup函数创建一个新的文件描述符,该新文件描述符和原有的文件描述符file_descriptor指向相同的文件、管道或者网络连接。

    dup总是返回系统中最小的可用文件描述符。dup2返回第一个不小于file_descriptor_two的整数值。

    3.readv函数和writev函数

    ssize_t readv(int fd, const struct iovec* vector, int count);  //将数据从文件描述符读到分散的内存块中, 即分散读。

    ssize_t writev(int fd, const struct iovec* vector, int count);  //将多块分散的内存数据一并写入文件描述符中,即集中写。

    4. sendfile函数

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

    ssize_t sendfile(int out_fd, int in_fd, off_t* offset, size_t count);

    in_fd是待读出内容的文件描述符,out_fd是待写入内容的文件描述符。offset参数指定从读入文件流的哪个位置开始读,如果为空,则使用读入文件流默认的起始位置。

    count参数指定在文件描述符in_fd和out_fd之间传输的字节数。

    in_fd必须是一个支持类似mmap函数的文件描述符,即它必须指向真实的文件,不能是socket和管道:而out_fd则必须是一个socket。

    5.mmap函数和munmap函数

    mmap函数用于申请一段内存空间,可以将这段内存作为进程间通信的共享内存,也可以将文件直接映射到其中。munmap释放该空间。

    void* mmap(void* start, size_t length, int prot, int flags, int fd, off_t offset);

    void* munmap(void* start, size_t length);

    flags参数:MAP_SHARED, 在进程中共享这段内存,对该内存的修改将反映到被映射的文件中,提供了进程间共享内存的POSIX方法。

    6.splice函数

    splice函数用于在两个文件描述符之间移动数据,也是零拷贝操作。

    ssize_t splice(int fd_in, loff_t* off_in, int fd_out, loff_t* off_out, size_t len, unsigned int flags);

    fd_in, fd_out必须至少一个为管道描述符。返回移动字节的数量。0表示没有移动。

    7.tee函数

    tee函数在两个管道文件描述符之间复制数据,也是零拷贝操作。不消耗数据,因此源文件描述符上数据仍然可以用与后续的读操作。

    ssize_t tee(int fd_in, int fd_out, size_t len, unsigned int flags);

    8. fcntl函数

    提供了对文件描述符的各种控制操作。

    int fcntl(int fd, int cmd, ...);

    将一个文件描述符设置为非阻塞的:

    int setnonblocking(int fd) {
        int old_option = fcntl(fd, F_GETFL);
        int new_option = old_option | O_NONBLOCK;
        fcntl(fd, F_SETFL, new_option);
        return old_option;
    }
  • 相关阅读:
    java基础知识
    谈谈休眠/睡眠/关机和laptop硬件寿命
    常用的git指令查询
    java swing scroll can not work
    不必要的windows服务
    工作分配问题
    回溯算法
    第四章上机实践
    算法第四章作业
    第三章上机实践
  • 原文地址:https://www.cnblogs.com/sssblog/p/12372614.html
Copyright © 2011-2022 走看看