2
簡單地說,在一個read
方法我檢查,如果一個變量爲0,如果是我把當前進程睡眠:如何正確地喚醒過程的中斷處理程序內
static ssize_t soc2e_read(struct file *filp, char __user *buf,
size_t count, loff_t * ppos)
{
...
struct soc2e_dev *soc2e = (struct soc2e_dev *)filp->private_data;
if (soc2e->bytes == 0)
{
if (wait_event_interruptible(soc2e->wlist, (soc2e->bytes > 0)))
return -ERESTARTSYS;
}
...
}
我必須在喚醒過程中斷處理程序:
static irqreturn_t soc2e_irq_handler(int irq, void *dev)
{
...
struct soc2e_dev *soc2e = dev;
...
soc2e->bytes += read_bytes;
wake_up_interruptible(&soc2e->wlist);
return IRQ_HANDLED;
}
我認爲(也驗證了)這裏可能是一個原子性問題。如果在if (soc2e->bytes == 0)
的read
方法和wait_event_interruptible
的調用之間發生中斷會發生什麼情況。也許這個過程在下一次中斷之前不會被喚醒。解決此問題的最佳方法是什麼?
酷!感謝羅蘭。但是,在這個過程被喚醒之後,我應該重新測試一下情況嗎?如果我有更多的進程,字節可以被其他消費者讀取...也許信號量可能是足夠的? – MirkoBanchi 2012-03-22 09:03:11
是的,如果情況可能改變,您需要再次檢查。通常,信號量通常不是正確的答案......內核習慣用法是用鎖來保護條件,並執行諸如「lock_state(); while(!condition){drop_lock(); wait_event ...() ; retake_lock();}「 – Roland 2012-03-26 21:41:22