伺服器程式設計——函式splice實現零拷貝使用解釋

readyao發表於2016-02-28

splice函式用於在兩個檔案描述符之間移動資料,也是零拷貝操作。

函式原型如下:

       #define _GNU_SOURCE         /* See feature_test_macros(7) */
       #include <fcntl.h>

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

        splice()  moves  data  between  two  file descriptors without copying between kernel address space and user address space.  It transfers up to len bytes of data from the file descriptor fd_in to the file descriptor fd_out, where one of the descriptors must refer to a pipe.


        If fd_in refers to a pipe, then off_in must be NULL.  If fd_in does not refer to a pipe and off_in is NULL, then bytes are read from fd_in  starting  from the  current  file  offset, and the current file offset is adjusted appropriately.  If fd_in does not refer to a pipe and off_in is not NULL, then off_in must point to a buffer which specifies the starting offset from which bytes will be read from fd_in; in this case,  the  current  file offset of fd_in is not changed.  Analogous statements apply for fd_out and off_out.


       The flags argument is a bit mask that is composed by ORing together zero or more of the following values:

       SPLICE_F_MOVE      Attempt  to  move  pages instead of copying.  This is only a hint to the kernel: pages may still be copied if the kernel cannot  move the pages from the pipe, or if the pipe buffers don't refer to full pages.  The initial implementation of  this  flag  was  buggy:  therefore  starting in Linux 2.6.21 it is a no-op (but is still permitted in a splice() call); in the future, a correct implementation may be restored.

       SPLICE_F_NONBLOCK  Do not block on I/O.  This makes the splice pipe operations nonblocking, but splice() may nevertheless block because  the  file descriptors that are spliced to/from may block (unless they have the O_NONBLOCK flag set).

       SPLICE_F_MORE      More  data  will  be  coming  in  a subsequent splice.  This is a helpful hint when the fd_out refers to a socket (see also the description of MSG_MORE in send(2), and the description of TCP_CORK in tcp(7))

       SPLICE_F_GIFT      Unused for splice(); see vmsplice(2).


相關文章