zoukankan      html  css  js  c++  java
  • IO流程中IO向量iovec

    作者:Younger Liu,本作品采用知识共享署名-非商业性使用-相同方式共享 3.0 未本地化版本许可协议进行许可。

    为了提高从磁盘读取数据到内存的效率,引入了IO向量机制,IO向量即struct iovec,在API接口在readvwritev中使用,当然其他地方也较多的使用它。抛砖引玉,聊一下自己对iovec的了解。

     

    readv & writev

         readv接口:从文件描述符fd所对应的的文件中读去count个数据段到多个buffers中,该bufferiovec描述,原型:

    #include <sys/uio.h>

     

    ssize_t readv(int fd,const struct iovec *iov, int count);

         writev接口:把count个数据buffer(使用iovec描述)写入到文件描述符fd所对应的的文件中,原型:

    #include <sys/uio.h>

     

    ssize_t writev(int fd,const struct iovec *iov, int count);

     

     

    iovec说明

    struct iovec成为IO向量,其结构如下;

    #include <sys/uio.h>

     

    struct iovec{

          void *iov_base; /* pointer to the start of buffer */

          size_t iov_len; /* size of buffer in bytes */

    }

    很明显,iov_base作为一个指针,用于记录buffer地址(一般为用户态地址)iov_len表示buffer的大小。

     

    在用户态或内核态中使用时,一般均采用指针的形式:struct iovec *iov。当然一般也给出其元素的个数count

    如何读写哪?将按照iov[0]iov[1]、…、iov[count-1]的顺序依次读写,并且他们在文件中的地址是连续的。

    返回值:(1) 成功,返回读写的字节数,这个字节数是所有iovec结构中iov_len的总和;(2)失败返回-1,并设置好errno

    iov_len的总和不能超过SSIZE_MAXcount需要大于0,小于IOV_MAX(<limits.h>),在linux1024 否则返回-1errno设置为EINVAL 

     

    实例

     writev:

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <string.h>
    #include <sys/uio.h>
    
    int main(){
    	struct iovec iov[3];
    	ssize_t nr;
    	int fd,i;
    	
    	char *buf[] = {
    		"The term buccaneer comes from the word boucan.
    ",
    		"A boucan is a wooden frame used for cooking meat.
    ",
    		"Buccaneer is the West Indies name for a pirate.
    " 
    	};
    	
    	fd = open("buccaneer.txt",O_WRONLY | O_CREAT | O_TRUNC);
    	if( fd == -1 ){
    		perror("open");
    		return 1;
    	}
    
    	for(i = 0; i < 3; i++){
    		iov[i].iov_base = buf[i];
    		iov[i].iov_len = strlen(buf[i]);
    	}
    	
    	nr = writev(fd,iov,3);
    	if(nr == -1){
    		perror("writev");
    		return 1;
    	}
    	printf("wrote %d bytes
    ",nr);
    
    	if(close(fd)){
    		perror("close");
    		return 1;
    	}
    	return 0;
    }


    readv:

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <sys/uio.h>
    
    int main(){
    	char foo[48],bar[51],baz[49];
    	struct iovec iov[3];
    	ssize_t nr;
    	int fd,i;
    
    	fd = open("buccaneer.txt",O_RDONLY);
    	if(fd == -1){
    		perror("open");
    		return 1;
    	}
    
    	iov[0].iov_base = foo;
    	iov[0].iov_len = sizeof(foo);
    	iov[1].iov_base = bar;
    	iov[1].iov_len = sizeof(bar);
    	iov[2].iov_base = baz;
    	iov[2].iov_len = sizeof(baz);
    
    	nr = readv(fd,iov,3);
    	if(nr == -1){
    		perror("readv");
    		return 1;
    	}
    
    	for(i = 0; i < 3; i++){
    		printf("%d: %s",i,(char *)iov[i].iov_base);
    	}
    
    	if(close(fd)){
    		perror("close");
    		return 1;
    	}
    	return 0;
    }

     

    致谢

    http://fuliang.iteye.com/blog/652297

    作者:Younger Liu,本作品采用知识共享署名-非商业性使用-相同方式共享 3.0 未本地化版本许可协议进行许可。

  • 相关阅读:
    VUE学习日记(十八) ---- 传递数据
    VUE学习日记(十七) ---- 组件数据函数
    VUE学习日记(十六) ---- 表行组件
    DataGridView控件使用Demo
    C# ADO.NET连接字符串详解
    SQL Server management studio使用sa连接时报错与伺服器的连接已成功,但在登入程序是发生错误
    Oracle Rac to Rac One Node
    online创建索引中途取消导致索引无法删除解决办法
    oracle常用hint添加
    C# url的编码解码,xml和json的序列化和反序列化
  • 原文地址:https://www.cnblogs.com/youngerchina/p/5624567.html
Copyright © 2011-2022 走看看