UNIX环境高级编程读书笔记(十二)—高级IO (3)

4.

名称::

pselect

功能:

指行I/O多路转接

头文件:

#include <sys/select.h>

函数原形:

int pselect(int masfdp1,fd_set *restrict readfds,fd_set *restrict writefds,fd_set excepfds,const struct timespec *restrict tsptr,const sigset_t *restrict sigmask);

参数:

maxfdpl    最大描述符加1

readfds     读描述符集   

writefds    写描述符集

excepfds    异常描述符集

tsptr       愿意等待时间

sigmask    信号屏蔽集

返回值:

若fd在描述符集中则返回非0值,否则返回0(FD_ISSET)

                                          pselect是select的一个变体,除以下几点外,pselect与select相同:

(1)       select的超时值用timeval结构指定,但pselect使用timespec结构指定。timespec以秒和纳秒表示超时值。

(2)       pselect的超时值被定义为const,这保证了调用pselect不会改变此值,。

(3)       对于paselect可以使用一可选的信号屏蔽字。若sigmask为空,那么在于信号有关的方面,pselect和select相同。否则,sigmask指向一信号屏蔽字,在调用pselect时,以原子操作的方式安装该信号屏蔽字。在返回时恢复以前的信号屏蔽字。

 

5.

名称::

poll

功能:

指行I/O多路转接

头文件:

#include <sys/select.h>

函数原形:

int poll(struct pollfd fdarray[],nfds_t nfds,int timeout);

参数:

fdarray      存放描述符集的数组

nfds        fdarray数组元素个数

timeout     超时等待时间

返回值:

准备就绪的描述符数,若超时则返回0,若出错则返回-1

  poll类似于select,但是其接口则有所不同。poll不时为每个状态(可读性,可写性和异常状态)构造一个描述符集,而是构造一个pollfd结构的数组,每个数组元素指定一个描述符编号以及其所关心的状态。

struct pollfd{

       int fd; 文件描述符

       shout events;

       shout revents;

};

       fdarray数组中的元素由nfds说明。

应将每个数组元素的events成员设置为下表的值。通过这些告诉内核我们对该描述符关系的时什么。返回时,内核设置revents成员,以说明对于该描述符已经发生了什么事件。

 

标志名

说明

POLLIN

POLLRDNORM

POLLRDBAND

POLLPRI

不阻塞地可读除高优先级外的数据(等效于POLLRDNORM|POLLRDBAD)

不阻塞地可读普通数据(优先级波段为0)

不阻塞地可读非0优先级波段数据

不阻塞地可读高优先级数据

POLLOUT

POLLWRNORM

POLLWRBAND

不阻塞地可写普通数据

与POLLOUT相同

不阻塞地可写非0优先级波段数据

POLLERR

POLLHUP

POLLNVAL

已出错

已挂断

描述符不引用一打开文件

       表头四行测试可读性,接着三行测试可写性,最后三行则是测试异常状态。最后三行是由内核在返回时设置的。即使在events字段中没有指定这三个值,如果相应条件发生,则在revents中也它们。

       当一个描述符被挂断后,就不能再写向该描述符。但是仍可能从该描述符读取数据。

poll的最后一个参数说明我们愿意等待多少时间。如同sellect一样,有三种不同情形:

      (1) timeout==-1永远等待,当所指定的描述符中的一个已准备好,或捕捉到一个信号时则返回。如果捕捉到一个信号,则poll返回-1,error设置为EINTR.

       (2)timeout==0 不等待。测试所有的描述符并立即返回。这是得到多个描述符的状态而不阻塞select函数的轮询方法。

       (3)timeout>0 等待timeout毫秒。当指定的描述符之一已准备好,或当指定的时间值已超过时立即返回。如果在超时还没有一个描述符准备好,则返回值是0。

 

三、读写多个缓冲区

6.

名称::

readv/writev

功能:

散布读/聚集写

头文件:

#include <sys/uio.h>

函数原形:

ssize_t readv(int filedes,const struct iovec *iov,int iovcnt);

ssize_t writev(int filedes,const struct iovec *iov,int iovcnt);

参数:

filedes     文件描述符

iov       指向iovec结构数组的一个指针。

iovcnt     数组元素的个数

返回值:

若成功则返回已读、写的字节数,若出错则返回-1

 readv和writev函数用于在一次函数调用中读、写多个非连续缓冲区。有时也将这两个函数成为散布读和聚集写。

       这两个函数的第二个参数是指向iovec结构数组的一个指针:

       struct iovec{

              void *iov_base;

              size_t iov_len;

       };

       writev以顺序iov[0]至iov[iovcnt-1]从缓冲区中聚集输出数据。writev返回输出的字节总数,通常,它应等于所有缓冲区长度之和。

       readv则将读入的数据按上述同样顺序散布读到缓冲区中。readv总是先填满一个缓冲区,然后再填写下一个。readv返回读到的总字节数。如果遇到文件结尾,已无数据可读,则返回0。

下面就是读多个缓冲区的例子:

/*12_4.c*/

#include <sys/uio.h>

#include <stdio.h>

#include <fcntl.h>

 

int main(int argc,char *argv[])

{

ssize_t size;

char buf1[9];

char buf2[9];

struct iovec iov[2];

 

fd1=open(argv[1],O_RDONLY);

fd2=open(argv[2],O_RDONLY);

fd3=open(argv[3],O_WRONLY);

 

size=read(fd1,buf1,sizeof(buf1));

printf(“%s size is:%d\n”,argv[1],size);

size=read(fd2,buf2,sizeof(buf2));

printf(“%s size is:%d\n”,argv[2],size);

 

iov[0].iov_base=buf1;

iov[0].iov_len=sizeof(buf1);

iov[1].iov_base=buf2;

iov[1].iov_len=sizeof(buf2);

 

size=writev(fd3,iov,2));

printf(“%s size is:%d\n”,argv[3],size);

 

close(fd1);

close(fd2);

close(fd3);

}

先用vi或cat建立三个文件(test1,test2,test3),test写入123456789,test写入abcdefghi. test3为空。

然后运行命令:

#./12_4 test1 test2 test3

在屏幕上会输出:

test1 size is:9

test2 size is:9

test3 size is:18

打开test3,文件内容为123456789abcdefghi.

程序先把test1和test2的内容分别读到缓冲区buf1和buf2中。然后用write把buf1

本书全面介绍了UNIX系统的程序设计界面—系统调用界面和标准C库提供的许多函数。 本书的前15章着重于理论知识的阐述,主要内容包括UNIX文件和目录、进程环境、进程控制、 进程间通信以及各种I/O。在此基础上,分别按章介绍了多个应用实例,包括如何创建数据库函数库, PostScript 打印机驱动程序,调制解调器拨号器及在伪终端上运行其他程序的程序等。 本书内容丰富权威, 概念清晰精辟,一直以来被誉为UNIX编程的“圣经”,对于所有UNIX程序员—无论是初学者还是专家级人士 —都是一本无价的参考书籍。 目 录 译者序 译者简介 前言 第1章 UNIX基础知识 1 1.1 引言 1 1.2 登录 1 1.2.1 登录名 1 1.2.2 shell 1 1.3 文件和目录 2 1.3.1 文件系统 2 1.3.2 文件名 2 1.3.3 路径名 2 1.3.4 工作目录 4 1.3.5 起始目录 4 1.4 输入和输出 5 1.4.1 文件描述符 5 1.4.2 标准输入、标准输出和标准 出错 5 1.4.3 不用缓存的I/O 5 1.4.4 标准I/O 6 1.5 程序和进程 7 1.5.1 程序 7 1.5.2 进程和进程ID 7 1.5.3 进程控制 7 1.6 ANSI C 9 1.6.1 函数原型 9 1.6.2 类属指针 9 1.6.3 原始系统数据类型 10 1.7 出错处理 10 1.8 用户标识 11 1.8.1 用户ID 11 1.8.2 组ID 12 1.8.3 添加组ID 12 1.9 信号 12 1.10 UNIX时间值 14 1.11 系统调用和库函数 14 1.12 小结 16 习题 16 第2章 UNIX标准化及实现 17 2.1 引言 17 2.2 UNIX标准化 17 2.2.1 ANSI C 17 2.2.2 IEEE POSIX 18 2.2.3 X/Open XPG3 19 2.2.4 FIPS 19 2.3 UNIX实现 19 2.3.1 SVR4 20 2.3.2 4.3+BSD 20 2.4 标准和实现的关系 21 2.5 限制 21 2.5.1 ANSI C限制 22 2.5.2 POSIX限制 22 2.5.3 XPG3限制 24 2.5.4 sysconf、pathconf 和fpathconf 函数 24 2.5.5 FIPS 151-1要求 28 2.5.6 限制总结 28 2.5.7 未确定的运行时间限制 29 2.6 功能测试宏 32 2.7 基本系统数据类型 32 2.8 标准之间的冲突 33 2.9 小结 34 习题 34 第3章 文件I/O 35 3.1 引言 35 3.2 文件描述符 35 3.3 open函数 35 3.4 creat函数 37 3.5 close函数 37 3.6 lseek函数 38 3.7 read函数 40 3.8 write函数 41 3.9 I/O的效率 41 3.10 文件共享 42 3.11 原子操作 45 3.11.1 添加至一个文件 45 3.11.2 创建一个文件 45 3.12 dup和dup2函数 46 3.13 fcntl函数 47 3.14 ioctl函数 50 3.15 /dev/fd 51 3.16 小结 52 习题 52 第4章 文件和目录 54 4.1 引言 54 4.2 stat, fstat和lstat函数 54 4.3 文件类型 55 4.4 设置-用户-ID和设置-组-ID 57 4.5 文件存取许可权 58 4.6 新文件和目录的所有权 60 4.7 access函数 60 4.8 umask函数 62 4.9 chmod和fchmod函数 63 4.10 粘住位 65 4.11 chown, fchown和 lchown函数 66 4.12 文件长度 67 4.13 文件截短 68 4.14 文件系统 69 4.15 link, unlink, remove和rename 函数 71 4.16 符号连接 73 4.17 symlink 和readlink函数 76 4.18 文件的时间 76 4.19 utime函数 78 4.20 mkdir和rmdir函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值