日期:2014-05-16  浏览次数:21011 次

应用层获得SIGIO信号如何区分是kill_fasync(poll_in)或kill_fasync(poll_out)产生的
static ssize_t xxx_write(...)
{
 ...
 echo "....">设备 完成写操作时发送信号
 if(dev->async_queue)
  kill_fasync(&dev->async_queue,SIGIO,POLL_IN);
}
static ssize_t xxx_read(...)
{
 ...
 完成读设备操作时发送信号
 if(dev->async_queue)
  kill_fasync(&dev->async_queue,SIGIO,POLL_OUT);
}
以上是驱动中的读写两个函数,在应用程序中都会获得SIGIO信号
signal(SIGIO,xxx);xxx为处理函数
我的问题是,如何在应用程序中区分到底是读完成后产生的SIGIO信号,还是写完成后产生的
求高手教下怎么在接受信号后把读写分开
例如,写完成后产生SIGIO信号,进入处理函数,经过什么判断知道是写完成,我们就进行读操作
反之一样

------解决方案--------------------
可否采用select函数进行查询啊
------解决方案--------------------
我觉得可以在驱动中设置一个布尔变量,表示是通知读还是写,再写一个比如ioctl函数来允许用户程序访问该变量。然后用户程序的信号处理函数在收到SIGIO时,通过ioctl检查该变量就可以知道是该读还是写了。当然这个变量可能在通知时又被新发生的读或写修改,这需要进行一些同步处理。
可以参照驱动和硬件之间的中断处理,在中断的上半部处理中,如果是共享中断号的设备,在发生中断时中断处理函数是无法通过传递来的参数识别出是哪个设备发生的中断,只知道是这几个设备中至少有一个发生了。识别方法就是,在中断处理函数中依次遍历这些设备,一般设备都会有一些状态寄存器标志是否有数据到来,是否发生中断等信息,访问这些寄存器就可以知道是否是这个设备发出的中断,这样查找直到发现某个设备发生中断。共享中断号就是把这么多的设备的中断进行分组,以便在中断发生时可以缩小查找范围,所有设备用一个中断线应该也可以,但每次都要全部遍历,代价很大。
在LZ的这个问题中,应用程序相当于驱动,驱动中的读和写就相当于两个共享中断号的硬件,异步通知相当于中断,布尔变量就相当于状态寄存器,类比一下就好理解了。
------解决方案--------------------
函数kill_fasync中参数POLL_IN表示可读,POLL_OUT表示可写。