readv 和 writev

Unix 系统已经长时间支持名为 readv 和 writev 的 2 个系统调用. 这些 read 和 write 的"矢量"版本使用一个结构数组, 每个包含一个缓存的指针和一个长度值. 一个 readv 调 用被期望来轮流读取指示的数量到每个缓存. 相反, writev 要收集每个缓存的内容到一起 并且作为单个写操作送出它们.

如果你的驱动不提供方法来处理矢量操作, readv 和 writev 由多次调用你的 read 和 write 方法来实现. 在许多情况, 但是, 直接实现 readv 和 writev 能获得更大的效率.

矢量操作的原型是:

ssize_t (*readv) (struct file *filp, const struct iovec *iov, unsigned long count, loff_t

*ppos);

ssize_t (*writev) (struct file *filp, const struct iovec *iov, unsigned long count, loff_t

*ppos);

这里, filp 和 ppos 参数与 read 和 write 的相同. iovec 结构, 定义于

<linux/uio.h>, 如同:

struct iovec

{

void   user *iov_base;   kernel_size_t iov_len;

};

每个 iovec 描述了一块要传送的数据; 它开始于 iov_base (在用户空间)并且有 iov_len 字节长. count 参数告诉有多少 iovec 结构. 这些结构由应用程序创建, 但是内核在调用 驱动之前拷贝它们到内核空间.

矢量操作的最简单实现是一个直接的循环, 只是传递出去每个 iovec 的地址和长度给驱动 的 read 和 write 函数. 然而, 有效的和正确的行为常常需要驱动更聪明. 例如, 一个磁 带驱动上的 writev 应当将全部 iovec 结构中的内容作为磁带上的单个记录.

很多驱动, 但是, 没有从自己实现这些方法中获益. 因此, scull 省略它们. 内核使用 read 和 write 来模拟它们, 最终结果是相同的.

原文地址:https://www.cnblogs.com/fanweisheng/p/11106337.html

时间: 2024-10-10 01:05:20

readv 和 writev的相关文章

readv和writev函数

readv 和 writev 函数用于在一次函数调用中读.写多个非连续缓冲区.有时也将这两个函数称为散布读和聚集写. #include <sys/uio.h> ssize_t readv(int fd, const struct iovec *iov, int iovcnt); ssize_t writev(int fd, const struct iovec *iov, int iovcnt); 这两个函数的第二个參数是指向 iovec 结构数组的一个指针: struct iovec { v

高级I/O函数(1)-writev、readv、sendfile函数

 1.前言 Linux提供了很多的高级I/O函数,它们在特定的条件下表现出优秀的特性.这里主要讨论的是和网络编程相关的几个. 用于读写数据的函数,包括writev/readv.sendfile. readv和writev函数 #include <sys/uio.h> ssize_t readv(int fd,const struct iovec* vector,int count); ssize_t writev(int fd,const struct iovec* vector,int co

nginx中writev函数的使用

nginx的代码非常的优秀,之前已经介绍了sendfile的使用来实现"内存零拷贝",今天我又理解了一下writev函数的使用,以nginx-1.6.0为例,在src/os/unix/ngx_writev_chain.c的113行,如下图: 可以man 2 writev看下函数的概念(与writev相对应的还有一个readv)writev是读取多个不连续的buffer然后集中写入. #include <sys/uio.h>       ssize_t readv(int f

《网络编程》先进 I/O

这部分是高级插座 I/O . 设置套接字超时报警,使用更方便的数据传输功能. 套接字 I/O 设置操作超时有三种方法: 转让 alarm 性能,制作时,它指定超时 SIGALRM 信号: 在 select 函数中设置超时堵塞等待 I/O,以替代直接堵塞在 read 或write 调用上: 使用 SO_RCVTIMEO 和 SO_SNDTIMEO 套接字选项(这两个选项仅仅是一部分实现支持). 以下使用 alarm 产生的 SIGALRM 信号为 connect 函数设置超时,当然系统会为 con

进程间通信(10) - 网络套接字(socket)[2]

1.前言 本篇文章的所有例子,基于RHEL6.5平台(linux kernal: 2.6.32-431.el6.i686). 在前一篇文章中(点此链接),已经介绍了socket(),bind(),listen(),connect(),accept()这些函数. 至此,服务器与客户机已经建立好了连接.可以调用网络I/O进行读写操作了,即实现网络中不同进程之间的通信.网络I/O操作有下面的几组函数: · read() / write() · readv() / writev() · send() /

Tinywebserver:一个简易的web服务器

这是学习网络编程后写的一个练手的小程序,可以帮助复习I/O模型,epoll使用,线程池,HTTP协议等内容. 程序代码是基于<Linux高性能服务器编程>一书编写的. 首先回顾程序中的核心内容和主要问题,最后给出相关代码. 0. 功能和I/O模型 实现简易的HTTP服务端,现仅支持GET方法,通过浏览器访问可以返回相应内容. I/O模型采用Reactor(I/O复用 + 非阻塞I/O) + 线程池. 使用epoll事件循环用作事件通知,如果listenfd上可读,则调用accept,把新建的f

ldd3-3 字符驱动程序

[scull的设计] [主设备号和次设备号] ls -l /dev/ 主设备号:标识设备对应的驱动程序. 次设备号:用于确定设备文件所指的设备. [设备编号的内部表达] dev_t类型 /linux/types.h 获取主设备号和次设备号 /linux/kdev_t.h MAJOR(dev_t dev); MAJOR(dev_t dev); 在source insight的符号列表窗口中搜索MAJOR可以找到这个宏的定义: 在source insight的引用查找中,可以搜到使用MAJOR宏的范

10.5 Interrupted System Calls

早期UNIX系统的一个特点就是:当进程被阻塞再一个"slow"的系统调用中的时候如果捕获到一个信号,系统调用就会被中断,然后系统调用返回一个错误,其中errno被设置为EINTR.这可以实现使用一些事件的发生来唤醒被阻塞的系统调用. 为了支持这一特性,系统调用被分为两类:slow的系统调用,以及其他系统调用,所谓的slow系统调用是指可能永远阻塞的系统调用,包括如下系统调用: 读操作可能会永远阻塞系统调用,如果对于某些文件类型来说数据还没有准备好的话(if data isn't pre

块设备驱动程序

通用块层 常用数据结构: bio 磁盘描述符 gendisk generic_make_request 是通用块层的入口点 io调度层: 请求队列:request_queue 请求描述符:request 块设备: block_device 注册块设备 register_blkdev    预定主设备号. 块设备文件操作描述符表: open  blkdev_open release blkdev_close llseek block_llseek read genric_file_read wrt