位,然后
将结果和这三种值相比较。
F[CD#*2]SETFL〓将文档状态标志配置为第3个参数的值(取为整型值)。能够更改的
几个标志
是:O[CD#*2]APPEND,O[CD#*2]NONBLOCK,O[CD#*2]SYNC和O[CD#*2]ASYNC。
F[CD#*2]GETOWN〓取当前接收SIGIO和SIGURG信号的进程ID或进程组ID。在126
2节中将
说明这两种43 BSD异步I/O信号。
F[CD#*2]SETOWN〓配置接收SIGIO和SIGURG信号的进程ID或进程组ID。正的arg指定
一个进程
ID。负的arg表示等于arg绝对值的一个进程组ID。
fcntl的返回值和命令有关。假如出错,任何命令都返回-1,假如成功则返回某个
其他值。
下列三种命令有特定返回值:F[CD#*2]DUPFD,F[CD#*2]GETFD连同F[CD#*2]GETOWN
。第一个
返回新的文档描述符,第二个返回相应标志,最后一个返回一个正的进程ID或一个
负的进程
组ID。
实例
程式34取指定一个文档描述符的命令行参数,并对于该描述符打印其文档标志说
明。
程式34〓对于指定的描述符打印文档标志
注意,我们使用了功能测试宏[CD#*2]POSIX[CD#*2]SOURCE,并且条件编译了POSI
X1中没
有定义的文档存取标志。下面显示了从Kornshell调用该程式时的几种情况:
$ aout 0</dev/tty
read only
$ aout 1>tempfoo
$ cat tempfoo
write only
$ aout 2 2>>tempfoo
write only,append
$ aout 5 5<>tempfoo
read write
Kornshell子句5<>tempfoo表示在文档描述符5上打开文档tempfoo供读、写。
实例
当修改文档描述符标志或文档状态标志时,必须谨慎,先要取得现在的标志值,然
后按照希
望修改他,最后配置新标志值。不能只是执行F[CD#*2]SETFD或F[CD#*2]SETFL命令
,这样会
关闭以前配置的标志位。
程式35是个对于一个文档描述符配置一个或多个文档状态标志的函数。
程式35〓对一个文档描述符打开一个或多个文档状态指标
假如我们将中间的一条语句改为
这就构成了另一个函数,我们称其为clr[CD#*2]fl,并将在某个后面的例子中用到
他。此语
句使当前文档状态标志值val和flags的反码逻辑和。
假如在程式33的开始处,加上下面1行以调用set[CD#*2]fl,则打开了同步写标
志。这就
造成每次write都要等待,直至数据已写到盘上再返回。在Unix中,通常write只是
将数据排
入队列,而实际的I/O操作则可能在以后的某个时刻进行。数据库系统很可能需要
使用O[CD#
*2]SYNC,这样,在系统崩溃情况下,他从write返回时就知道数据已确实写到了盘
上。
在程式运行时,配置O[CD#*2]SYNC标志会增加时钟时间。为了测试这一点,我们运
行程式3
3,他从盘上的一个文档中将15Mbyle复制到另一个文档中。然后,在此程式中
配置O[CD
#*2]SYNC标志,使其运行做上述同样工作,将两者得到的结果进行比较,这示于图
36中。
图36〓用同步写(O[CD#*2]SYNC)的时间结果
图36中的3行都是在BUFSIZ为8192的情况下测量得到的。图31中的结果所测量
的情况是
读一个盘文档,然后写到/dev/null,所以没有盘输出。图36中的第2行对应于读
一个盘文
件,然后写到另一个盘文档中。这就是为什么图36中第1,2行有差别的原因。在
写盘文档
时,系统时间增加了,其原因是系统核需要从进程中复制数据,并将数据排入队列
以便由盘
驱动器将其写到盘上去。当写至盘文档时,时钟时间也增加了。当进行同步写时,
系统时间
稍稍增加,而时钟时间则增加为6倍。
在这一例子中,我们看到了fcntl的必要性。我们的程式在一个描述符(标准输出)
上进行操
作,但是根本不知道由shell打开的相应文档的文档名。因为这是shell打开的,于
是可能在
打开时,按我们的需要配置O[CD#*2]SYNC标志。fcntl则允许当只知道打开文档的
描述符时
能够修改其性质。在说明非阻塞管道时(142节),我们也将了解到,由于我们对
pipe所具
有的标识只是其描述符,所以也需要使用fcntl的功能。
314〓ioctl函数
ioctl函数是I/O操作的杂物箱。不能用本章中其他函数表示的I/O操作通常都能用
ioctl表示
。终端I/O是ioctl的最大使用方面(在第十一章中,我们会了解到POSIX1已用
新的函数
代替ioctl进行终端I/O操作。)
#include <unistdh> /* SVR4 */
#include <sys/ioctlh>/* 43 BSd */
int ioctl(int filedes,int request,);
返回:出错为-1,若成功则为其他源
ioctl函数不是POSIX1的一部分,但是,SVR4和43 BSD用其进行很多杂项设备
操作。
我们所示的原型是SVR4和43 BSD所使用的,而较早的贝克莱系统则将第2个参数
说明为uns
igned long。因为第2个参数总是个头文档中的定义名,所以这种细节并没有什
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!



