《unix环境高级编程》通读学习笔记(四)(第12章)
上一篇 / 下一篇 2007-07-28 17:40:27 / 个人分类:unix环境高级编程的学习记录
第12章 高级I/O
{/E"?_:L v4}S)S0
1AU9S!b?1Fj012.1 引言
f7B:m.jy,Y6EAr012.2 非阻塞I/O
c6N;i(d
cN&eZ0低速系统调用是可能会使进程永远阻塞的一类系统调用.
5?'hZ-qHY Wa0非阻塞I/O使我们可以调用不会永远阻塞的I/O操作,例如open,read和write。如果这种操作不能完成,则立即出错返回,表示该操作如继续执行将继续阻塞下去。
eh3w$iZJ)}012.3 记录锁51Testing软件测试网#N,U+U!i N#qQ1~
记录锁(record locking)的功能是:一个进程正在读或修改文件的某个部分时,可以阻止其他进程修改同一文件区。51Testing软件测试网8Hkh.R\9]7h%d(P
12.3.1 历史
M.`/HT.}f*[J012.3.2 fcntl记录锁51Testing软件测试网WAdN@o:lE$@
fcntl函数的原型51Testing软件测试网.U#c+_aAZb8KM8Fr
---------------------------------------------------------------------
vci6}$d0#include <sys/types.h>51Testing软件测试网s~p6[0[u U
#include <unistd.h>
"R'|g!pEc1Uc!u^0#include <fcnt1.h>
cRcJD#w;T$R0int fcnt1(int filedes,int cmd,.../* struct flock *flockptr */);51Testing软件测试网%D%j){]3WA1eb
返回:若成功则依赖于c m d(见下),若出错则为- 1
3]R}#DfV3t {3C!}&J0---------------------------------------------------------------------
wrPMH8eo012.3.3 锁的隐含继承和释放
DEr:[!Y5nB6q0关于记录锁的自动继承和释放有三条规则:
u%c.JlS
A6]
O0(1) 锁与进程、文件两方面有关。51Testing软件测试网+\ |^E!jn;@5~ K
(2) 由fork产生的子程序不继承父进程所设置的锁。
8q7N*k Vo
G}9J0(3) 在执行exec后,新程序可以继承原执行程序的锁。51Testing软件测试网!jn9g2o5b5] @
12.3.4 4.3+BSD的实现51Testing软件测试网 gspH7n Wm _+n
12.3.5 建议性锁和强制性锁
;X.{0R)?n*z'MZ:V0考虑数据库存取例程序。如果该库中所有函数都以一致的方法处理记录锁,则称使用这些函数存取数据库的任何进程集为合作进程(cooperating process)。如果这些函数是唯一的用来存取数据库的函数,那么它们使用建议性锁是可行的。51Testing软件测试网tx4^m5R+h
强制性锁机制中,内核对每一个open、read和write都要检查调用进程对正在存取的文件是否违背了某一把锁的作用。
pc9H7\IE/[012.4 流
zfObcZ
g3p0流是系统V提供的构造内核设备驱动程序和网络协议包的一种通用方法。51Testing软件测试网QI2o_&X7|
流在用户进程和设备驱动程序之间提供了一条全双工通路。流无需和实际硬件设备直接对话—流也可以用作为伪设备驱动程序。图12-5示出了一个简单流的基本结构。
9ny*C`H0图12-6示出了一个包含一个处理模块的流。
[
O0eN`012.4.1 流消息
pt!r C@}0流的所有输入和输出都基于消息。流首和用户进程使用read、write、getmsg、getpmsg、putmsg和putpmsg交换消息。在流首、各处理模块和设备驱动程序之间,消息可以顺流而下,也可以逆流而上。51Testing软件测试网Zn0X&x1z8Pf
有约2 5种不同类型的消息,但是只有少数几种用于用户进程和流首之间。其余的则只在内核中顺流、逆流传送。51Testing软件测试网'w0b;y/zDi)|k
12.4.2 putmsg和 putpmsg函数51Testing软件测试网qQ uuik#g
putmsg和putpmsg函数用于将流消息(控制信息或数据,或两者)写至流中。
(n'B[&hTq~.Ukw012.4.3 流ioct1操作51Testing软件测试网@W)tx'm!q7O
ioctl函数,它能做其他I / O函数不能处理的事情。流系统中继续采用了该函数。
D%b{FB4{012.4.4 write至流设备
cs1rEK012.4.5 写方式
+Xx R%Lv012.4.6 getmsg和 getpmsg函数
'kI XM$Z7nU4x!~ C012.4.7 读方式
"E)wP;SB)^012.5 I/O多路转接51Testing软件测试网6B{:Jo;Pj6F
当从一个描述符读,然后又写到另一个描述符时。如果必须读两个描述符又将如何呢?如果仍旧使用阻塞I / O,那么就可能长时间阻塞在一个描述符上,而另一个描述符虽有很多数据却不能得到及时处理。所以为了处理这种情况显然需要另一种不同的技术。
2X4[P5s,nX{X0一种比较好的技术是使用I/O多路转接(I/O multiplexing)。其基本思想是:先构造一张有关描述符的表,然后调用一个函数,它要到这些描述符中的一个已准备好进行I/O时才返回。在返回时,它告诉进程哪一个描述符已准备好可以进行I/O。
Xu/C)M)a/r
e012.5.1 select函数51Testing软件测试网_r5fC+r
select函数使我们在SVR4和4.3+BSD之下可以执行I/O多路转接。
o$W\"suv012.5.2 poll函数
c:T[5Me`I1|
[T0SVR4的poll函数类似于select,但是其调用形式则有所不同。我们将会看到,poll与流系统紧紧相关。51Testing软件测试网5`p+P'~Q_&d~
51Testing软件测试网,GH$~WN)N
12.6 异步I/O
4Q!wQ0u1x$EC0使用select和poll可以实现异步I/O。关于描述符的状态,系统并不主动告诉我们任何信息,我们需要主动地进行查询(调用select或poll)。SVR4和4.3+BSD提供了使用一个信号(在SVR4中是SIGPOLL,在4.3+BSD中是SIGIO)的异步I/O方法,该信号通知进程,对某个描述符所关心的某个事件已经发生。51Testing软件测试网*I fwFgV
12.6.1 SVR451Testing软件测试网_ nl3^#_bi
12.6.2 4.3+BSD51Testing软件测试网R(qp J+S6Ym8us
,m'b1SS:f)IZc*o012.7 readv和writev函数51Testing软件测试网5X*MI$\IYt
readv和writev函数用于在一个函数调用中读、写多个非连续缓存。51Testing软件测试网T[t:fG [F j
--------------------------------------------------------------------51Testing软件测试网9j*A6Li8?~(I7]^m
#include <sys/types.h>51Testing软件测试网/gv?
K$Y
K s't&~
#include <sys/uio.h>
(v fH)A!m7r0#include <sys/types.h>51Testing软件测试网9rgDh6b9^
#include <sys/uio.h>
M;n8~AE8X2v7t0ssize_t readv(int filedes,const struct ioveciov[ ],int iovcnt);