我有一个想要向用户发送状态更改通知的驱动程序。在当前的实现中,它使用proc文件系统来执行此操作。读取过程围绕proc文件系统read()
循环。 read()
wait_event_interruptible()
阻塞write_new_data()
,直到内核获得中断,导致call wake_up_interruptible()
函数转移到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()
,调用{{1}},但没有等待的线程等待... 注意:这一切都发生在单处理器系统上。此外,只有一个线程读取和一个线程写入新数据。
如何避免错过第二个中断? (一种解决方案是使用netlink套接字,但我想知道是否有办法在/ proc land中进行)
答案 0 :(得分:4)
Dan,这是wait_event_interruptible的代码:
#define wait_event_interruptible(wq, condition) \
({ \
int __ret = 0; \
if (!(condition)) \
__wait_event_interruptible(wq, condition, __ret); \
__ret; \
})
如果在“if(!(condition))”和“__wait_event_interruptible”之间发生中断,则会发生休眠,读取过程将被阻塞,直到发生另一个中断。
答案 1 :(得分:2)
由于在调用wait_event_interruptible
和flag = 0
之间可能会发生中断,因此会以不受欢迎的方式影响flag
变量。
请注意,即使在UP计算机上,内核也可能是抢占式的,具体取决于配置,因此该代码会受到影响。
另外,我建议不要使用简单的'int'标志。相反,您应该使用atomic_t
和atomic_dec/inc_*
操作。请参阅内核中的完成实现,它与您在此处执行的操作类似。
关于问题本身:
如果您查看wait_event_interruptible
的代码,您会看到如果条件为真则不会发生睡眠 - 所以您的问题不是问题。