linux I/O possible

在linux环境下编写应用程序的同学,肯定会遇到过程序编译没问题,但是运行时却出现奇奇怪怪的问题的现象。
比如,这次要说到的这个现象,程序运行到读取外设数据的时候,弹出
“I/O possible”,然后程序就退出的现象:

首先

大概猜一下,提示的是什么意思?I O 字面上,基本就能确定,是输入与输出的意思;possible?可能?什么可能呢?输入输出可能?
显然不太对,再猜一下,可能意思就是数据可能来了。

然后

在进行串口或者网络编程的时候,数据的到来时刻是未知的。一般的书籍,对于数据的处理就是两种:轮询或者异步IO。
轮询,即是poll的方式,不停的查询。
异步IO,即是数据来了发信号。

其实,对于两种方式的优劣,并没有很明显的区分。只是看具体的程序设计。这时候,发现周围的人,对异步IO比较狂热,可能是受到了,轮询是纯粹浪费时间的思想的侵蚀。

然后呢,说到轮询,在linux下编程,很多人自然用到了select ,pselect函数。

说到这里,想起来曾经看到同行说到的一句话,能用轮询的就不要用异步。

最后

说了这么多废话,其实出现问题的原因,在于你的函数的初始化,误用了fcntl。不管你是否真正理解了函数的作用,对fnctl这个函数请不要乱用!

fcntl

函数用法:

fcntl(fd, F_SETOWN, getpid());

函数的实现,其实对应了SIGIO信号。即当有数据到来时,主动给所注册的进程发送SIGIO信号,在linux环境下,很多信号的默认行为就是终止进程,SIGIO也不例外。

为什么会这样

用到了fcntl,却没有注册信号处理函数。当然,信号到来时,进程留给你的只有一行字符串“I/O possible”

怎么办

a.要么删除fcntl ,F_SETOWN的代码行,继续用select调用
b.保留F_SETOWN的调用,添加SIGIO的信号处理函数。主循环即可以用sigsuspend调用来等待信号的到来了。

参考资料

1.http://davmac.org/davpage/linux/async-io.html
2.http://www.linuxquestions.org/questions/programming-9/i-o-possible-message-with-select-892241/

Logo

更多推荐