簡介I/O向量、sendv、writev

    在我們瞭解使用附屬數據工作的複雜函數之前,我們應該熟悉被readv(2)與writev(2)系統調用所使用的I/O向量。我們不僅將會發現這些函數是十分有用的,而他們的工作方式也被引入了一些附屬數據函數中。這會使得後面的理解更爲容易。
I/O向量(struct iovec)
readv(2)與writev(2)函數都使用一個I/O向量的概念。這是由所包含的文件定義的:
#include 
sys/uio.h頭文件定義了struct iovc,其定義如下:
struct iovec {
    ptr_t iov_base; /* Starting address */
    size_t iov_len; /* Length in bytes */
};
struct
iovec定義了一個向量元素。通常,這個結構用作一個多元素的數組。對於每一個傳輸的元素,指針成員iov_base指向一個緩衝區,這個緩衝區是存放
的是readv所接收的數據或是writev將要發送的數據。成員iov_len在各種情況下分別確定了接收的最大長度以及實際寫入的長度。
readv(2)與writev(2)函數
這些函數是作爲read與write函數的衍生函數而被人所知的。他們以這樣的方式進行設計是因爲他們可以在一個原子操作中讀取或是寫入多個緩衝區。這些函數的原型如下:
#include 
int readv(int fd, const struct iovec *vector, int count);
int writev(int fd, const struct iovec *vector, int count);
這些函數需要三個參數:
要在其上進行讀或是寫的文件描述符fd
讀或寫所用的I/O向量(vector)
要使用的向量元素個數(count)
這些函數的返回值是readv所讀取的字節數或是writev所寫入的字節數。如果有錯誤發生,就會返回-1,而errno存有錯誤代碼。注意,也其他I/O函數類似,可以返回錯誤碼EINTR來表明他被一個信號所中斷。
使用writev的例子
下面的程序代碼展示瞭如何使用writev函數將三個獨立的C字符串作爲一次寫操作寫入標準輸出。
/*
* writev.c
*
* Short writev(2) demo:
*/
#include 
int main(int argc,char **argv)
{
    static char part2[] = "THIS IS FROM WRITEV";
    static char part3[]    = "]/n";
    static char part1[] = "[";
    struct iovec iov[3];
    iov[0].iov_base = part1;
    iov[0].iov_len = strlen(part1);
    iov[1].iov_base = part2;
    iov[1].iov_len = strlen(part2);
    iov[2].iov_base = part3;
    iov[2].iov_len = strlen(part3);
    writev(1,iov,3);
    return 0;
}
編譯運行程序:
$ make writev
gcc -g -c -D_GNU_SOURCE -Wall -Wreturn-type writev.c
gcc writev.o -o writev
$ ./writev
[THIS IS FROM WRITEV]
$
當程序運行時,我們可以看到無論所引用的緩衝區是如何分散,所有的緩衝區都會被輸出形成最終的字符串。
也許我們希望多花一些時間來修改這個程序並做各種測試,但是要注意一定要將iov[[]數組分配得足夠大。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章