原文出处:http://blog.csdn.net/yanhaoliqian/article/details/6248356
何谓阻塞与非阻塞I/O?简单来说就是对I/O操作的两种不同的方式。
阻塞:当操作I/O设备时,如果不能得到相应的资源,则该进程进入休眠状态,被从调度器的队列中移走,直到等待的条件满足。
阻塞的读取一个字符:
char buf;
fd = open("/dev/ttyS1",O_RDWR);
.....
res = read(fd,&buf,1); //当串口上有输入时才返回,没有输入则进程挂起睡眠
if(res == 1)
{
printf("%c/n",buf);
}
非阻塞:当不能对I/O设备进行操作时,它或者放弃,或者不停的查询,直到可以进行操作为止。
非阻塞的读一个字符:
char buf;
fd = open("/dev/ttyS1",O_RDWR|O_NONBLOCK);//O_NONBLOCK 非阻塞标识
.....
while(read(fd,&buf,1)!=1);//串口上没有输入则返回,所以循环读取
printf("%c/n",buf);
阻塞操作常常用等待队列来实现,而非阻塞操作用轮询的方式来实现。
非阻塞I/O的操作在应用层通常会用到select()和poll()系统调用查询是否可对设备进行无阻塞访问。select()和poll()系统调用最终会引发
设备驱动中的poll()函数被调用。
应用层的select()原型为:int select(int numfds,fd_set *readfds,fd_set *writefds,fd_set *exceptionfds,
struct timeval *timeout); numfds 的值为需要检查的号码最高的文件描述符加1,若select()在等待timeout时间后,若没有文件描述符准备好则返回。
应用程序为:
#inlcude---
---
main()
{
int fd,num;
char rd_ch[BUFFER_LEN];
fd_set rfds,wfds; //读写文件描述符集
//以非阻塞方式打开/dev/globalfifo设备文件
fd = open("/dev/globalfifo",O_RDWR|O_NONBLOCK);
if(fd != -1)
{
//FIFO 清零
if(ioctl(fd,FIFO_CLEAR,0) < 0)
{
printf("ioctl cmd failed /n");
}
while(1)
{
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_SET(fd,&rfds);
FD_SET(fd,&wfds);
select(fd+1,&rfds,&wfds,null,null);
if
}
}
}