之前在开发驱动的时候,我没有使用wait_event_interruptible(...),但是现在我有了尝试的欲望。而且我无法理解第二个参数的含义:
- 这是睡眠标志。
- 这是唤醒标志。
在 Jonathan Corbet 的“圣经”LDD3 中(从我的角度来看)模糊不清。它使用英语双重否定,可以这样翻译。俄语翻译说“只要条件评估为真,进程就会继续休眠。”
他在微小的 sleepy.c 驱动程序中给出的示例
static DECLARE_WAIT_QUEUE_HEAD(wq);
static int flag = 0;
ssize_t sleepy_read (struct file *filp, char __user *buf, size_t count, loff_t *pos)
{
printk(KERN_DEBUG "process %i (%s) going to sleep\n",
current->pid, current->comm);
wait_event_interruptible(wq, flag != 0);
flag = 0;
printk(KERN_DEBUG "awoken %i (%s)\n", current->pid, current->comm);
return 0; /* EOF */
}
ssize_t sleepy_write (struct file *filp, const char __user *buf, size_t count,
loff_t *pos)
{
printk(KERN_DEBUG "process %i (%s) awakening the readers...\n",
current->pid, current->comm);
flag = 1;
wake_up_interruptible(&wq);
return count; /* succeed, to avoid retrial */
}
似乎证实了这个论点。
但是,如果您查看此宏的文本,那么(恕我直言)事实证明 - 相反:
#define wait_event_interruptible(wq, condition) \
({ \
int __ret = 0; \
if (!(condition)) \
__wait_event_interruptible(wq, condition, __ret); \
__ret; \
})
我不明白什么?
这是一个“唤醒标志”(尽管术语“条件”更合适,因为它仍然是宏中的表达式)。
在英文版中,恕我直言,所有内容都非常清楚地写在内核注释中的文档中:
LDD3 中有什么:
这个例子完全符合这一点;我不明白这怎么可能被忽视......除非,由于这个问题只是在深夜/清晨提出的,所以并不是所有的否定都可以计算在内。
而且在俄文翻译中,显然有一个错误……据我了解,这不是官方的,给出的示例也不是唯一的缺陷……如果您愿意,可以尝试联系其作者并指出错误...