非阻塞I/O

低速系统调用是可能会使进程永远阻塞的一类系统调用,他们包括下列调用:

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);

猜你喜欢

转载自blog.csdn.net/wocaoqwerty/article/details/40072939