低速系统调用是可能会使进程永远阻塞的一类系统调用,他们包括下列调用:
1:如果某些文件类型(例如管道,终端设备和网络设备)的数据并不存在,则读操作可能会使调用者永远阻塞.
2:如果数据被能被上诉童言类型的文件接受(由于管道中无空间,网络流控制等),则写操作也会使调用者永远阻塞.
3:在某种条件发生之前,打开某些类型的文件会被阻塞(例如打开一个终端设备可能需要等到与之连接的调制解挑器应答;有例如在没有其他进程以读模式打开的FIFO上用写模式打开FIFO,那么也要等待).
4:对已经加上强制性记录锁的文件进行读,写.
5:某些ioctl操作.
6:某些进程间通信函数.
对于一个给定的描述符有两种方法对其制定非阻塞I/O:
1:如果调用open获得描述符,则可制定O_NONBLOCK标志.
2:对于已经打开的一个描述符,则可调用fcntl,有该函数打开O_NONBLOCK文件状态标志.
#include<stdio.h>
#include<errno.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
char buf[500000];
int main(){
int ntowrite,nwrite;
char *ptr;
ntowrite=read(STDIN_FILENO,buf,sizeof(buf));
fprintf(stderr,"read %d bytes\n",ntowrite);
ptr=buf;
fcntl(STDOUT_FILENO,F_SETFL,O_NONBLOCK);
while(ntowrite>0){
nwrite=write(STDOUT_FILENO,ptr,ntowrite);
if(nwrite>0){
fprintf(stderr,"write %d bytes\n",nwrite);
ptr+=nwrite;
ntowrite-=nwrite;
}
}
fcntl(STDOUT_FILENO,F_SETFL,0);
exit(0);
}
向终端输出数据时,由于是慢速,会多次调用write函数.如果一下语句注释掉,则是阻塞I/O.
fcntl(STDOUT_FILENO,F_SETFL,O_NONBLOCK);