我有一个驱动程序想要向用户发送有关状态更改的通知。在当前的实现中,它使用proc文件系统来执行此操作。读取过程围绕read()
循环到proc文件系统。 read()
块与wait_event_interruptible()
,直到内核得到一个中断,导致write_new_data()
函数call wake_up_interruptible()
。这里是基本的代码(去掉所有不需要的杂波):wait_event和wake_up之间的竞争条件
static int flag=0;
DECLARE_WAIT_QUEUE_HEAD(info_wq);
//user process call read() on /proc/myfile to get to this function
int my_proc_read (struct file *filp, char *buf, size_t count, loff_t *pos)
{
wait_event_interruptible(info_wq, flag != 0);
flag = 0;
//copy buffers to user
return 0;
}
//when an interrupt comes it schedules this function on the systems' work queue
void write_new_data()
{
//fill buffer with data
flag = 1;
wake_up_interruptible(&info_wq);
}
现在考虑下面的流程:
- 用户进程调用
read()
,然后等待。 - 发生中断 - >
write_new_data()
被调用。写数据并致电wake_up_interruptible()
。 read()
被唤醒,读取数据但进程没有重新运行读取(没有安排 运行,没有得到它,因为下一个中断...)。发生- 中断 - >
write_new_data()
再次被触发,调用wake_up_interruptible()
但没有等待线程正在等待... - 过程调用read和块。
注意:这一切都发生在单处理器系统上。另外只有一个线程读取和一个线程写入新数据。
如何避免丢失第二个中断? (一种解决方案是使用netlink的插座,但我不知道是否有一种方法可以做到这一点在/ proc土地)
是什么样的驱动程序?以及它正在追查什么状态? –