非阻塞模式的read和write

非阻塞模式的read和write

我们知道read和write都是阻塞模式下的IO函数,如果没有可以读的,程序就会卡在read上,同样的,想要往fd里面写,如果fd里面是空的也会卡住,结合socket编程,我们很容易理解,对方没数据发过来,就read不出来,如果我没发数据,也就没法write。下面这个程序很好说明这一点。

[cpp]

#include<unistd.h>
#define SIZE 100
int main(void)
{
int n;
char buf[SIZE];
while(n=read(STDIN_FILENO,buf,SIZE)) //读取标准输入到buf中,返回读取字节数。
{
if(n!=write(STDOUT_FILENO,buf,n)) 把buf 写到标准输出中
perror(“write error”);
}
if(n<0) perror(“read error”);
return 0;
}

[/cpp]

某些情况下,我们可以利用fcntl改变对一个文件描述符的属性,比如变成NONBLCOK,也就是非阻塞模式。

首先我们需要传入一个flags的参数进去,这个可以先把一个int类型的参数取得当前STDIN_FILENO的文件描述符类型.

[cpp]

int flags;
flags = fcntl(STDIN_FILENO, F_GETFL);

[/cpp]

然后增加其的一个属性。

[cpp]flags!=O_NONBLCOK;[/cpp]

 然后在通过fcntl增加STDIN_FILENO的一个属性,非阻塞。

[cpp]fcntl(STDIN_FILENO, F_SETFL, flags)[/cpp]

 下面我们试一试这时的特性。

[cpp]

#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#define MSG_TRY “try again\n”
int main(void)
{
char buf[10];
int n;
int flags;
flags = fcntl(STDIN_FILENO, F_GETFL);
flags |= O_NONBLOCK;
if (fcntl(STDIN_FILENO, F_SETFL, flags) == -1) {
perror(“fcntl”);
exit(1);
}
tryagain:
n = read(STDIN_FILENO, buf, 10);
if (n < 0) {
if (errno == EAGAIN) {
sleep(1);
write(STDOUT_FILENO, MSG_TRY, strlen(MSG_TRY));
goto tryagain;
}
perror(“read stdin”);
exit(1);
}
write(STDOUT_FILENO, buf, n);
return 0;
}

[/cpp]

文章来源:hi.baidu.com/anheizzq