日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

linux文件IO与内存映射:分散/聚集IO技术(scatter-gather)

發(fā)布時間:2023/11/27 生活经验 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux文件IO与内存映射:分散/聚集IO技术(scatter-gather) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

根據(jù)上文我們學(xué)習到的用戶空間的IO緩沖區(qū),操作系統(tǒng)為了減少系統(tǒng)調(diào)用的次數(shù),節(jié)省系統(tǒng)開銷,提出了用戶空間的IO緩沖區(qū),即為用戶空間的文件讀寫開辟一段可以利用setvbuf配置大小的內(nèi)存空間來作為文件IO緩沖區(qū)。


描述

為了在以上IO緩沖區(qū)的基礎(chǔ)上更進一步得減少系統(tǒng)調(diào)用的次數(shù),提出了分散/聚合IO技術(shù),總體上是使用了單個向量的IO操作代替了多個向量的IO操作。
讀文多個件的時候?qū)膒age cache中讀到的內(nèi)容先讀入到一個IO緩沖區(qū)數(shù)據(jù)結(jié)構(gòu)中,再由一個緩沖區(qū)分別分散返回到多個文件緩沖區(qū)中;寫文件的過程與讀文件的過程剛好相反,即將多個文件緩沖區(qū)的內(nèi)容聚合寫到一個緩沖區(qū)中,寫入page cache中,從而更高得提升系統(tǒng)調(diào)用效率。

實現(xiàn)

實現(xiàn)scatter-gather技術(shù)的系統(tǒng)調(diào)用原型如下:

  • 頭文件<sys/uio.h>

  • 函數(shù)使用:
    ssize_t readv(int fd, const struct iovec *iov, int iovcnt);
    ssize_t writev(int fd, const struct iovec *iov, int iovcnt);

  • 函數(shù)參數(shù)
    fd :打開的文件描述符
    iov: IO向量數(shù)據(jù)結(jié)構(gòu)內(nèi)容如下,每個結(jié)構(gòu)體成員代表一個buffer:

     struct iovec {void  *iov_base;    /* Starting address */size_t iov_len;     /* Number of bytes to transfer */};
    

    iovcnt:IO向量的個數(shù)

    這兩個系統(tǒng)調(diào)用的底層仍然是使用read/write系統(tǒng)調(diào)用,只是對IO 緩沖區(qū)做了聚合,支持多個IO緩沖區(qū)內(nèi)容聚合到同一個IO向量中

代碼如下:
writev.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/uio.h>
#include <fcntl.h>int main(int argc, char *argv[])
{ssize_t count = 0;int fd, i = 0;char *buf[]={"buffer1\n","buffer2\n","buffer3\n"};fd = open(argv[1], O_WRONLY|O_CREAT, 0666);if (-1 == fd) {printf("open failed \n");_exit(-1);}//將三個IO緩沖區(qū)的文件聚合為一個IO向量struct iovec iov[3];for (i ; i < 3; ++i) {iov[i].iov_base = buf[i];iov[i].iov_len = sizeof(buf[i]) + 1;printf("iovec[%d] size is %ld \n",i,iov[i].iov_len);}//寫入一個文件count = writev(fd, iov, 3);if (-1 == count) {printf("writev failed\n");_exit(-1);}close(fd);return 0;
}

readv.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/uio.h>
#include <fcntl.h>int main(int argc, char *argv[])
{ssize_t count = 0;int fd, i = 0;char buf1[9],buf2[9],buf3[9];//生成一個文件,可以傳入聚合IO緩沖區(qū)的文件fd = open(argv[1], O_RDONLY,0666);if (-1 == fd) {printf("open failed \n");_exit(-1);}//對IO向量中的各個IO緩沖區(qū)進行地址和內(nèi)容大小賦值struct iovec iov[3];iov[0].iov_base = buf1;iov[0].iov_len = sizeof(buf1);	iov[1].iov_base = buf2;iov[1].iov_len = sizeof(buf2);	iov[2].iov_base = buf3;iov[2].iov_len = sizeof(buf3);	//從page cache讀入的一個向量會分散到三個緩沖區(qū)中count = readv(fd,iov,3);if (-1 == count) {printf("writev failed\n");_exit(-1);}for (i ; i < 3; ++i) {printf(" %s",(char *)(iov[i].iov_base));}prinft("buf1 %s\n",buf1);prinft("buf2 %s\n",buf2);prinft("buf3 %s\n",buf3);close(fd);return 0;
}

編譯輸出如下:
gcc writev.c -o writev
gcc readv.c -o readv

zhang@ubuntu:~/Desktop/cpp_practice$ ./writev  writevfile
iovec[0] size is 9 
iovec[1] size is 9 
iovec[2] size is 9 
zhang@ubuntu:~/Desktop/cpp_practice$ ./readv writevfile buffer1buffer2buffer3
buf1 buffer1buf2 buffer2buf3 buffer3

總結(jié)

以上是生活随笔為你收集整理的linux文件IO与内存映射:分散/聚集IO技术(scatter-gather)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。