[英]Why use wake_up_all() and not wake_up_interruptible()?
[英]How do poll_wait() and wake_up_interruptible() work in sync?
我正在編寫一個類似於 uio 的字符設備。 https://elixir.bootlin.com/linux/latest/source/drivers/uio/uio.c 。 我看到該進程在輪詢文件操作中通過poll_wait()
進入睡眠狀態,並在發生中斷時喚醒wake_up_interruptible()
。 我無法理解 wait 和 wake_up 呼叫是如何同步的。
考慮這個案例。
poll()
系統調用是在用戶空間中完成的。
uio_poll()
被執行。
就在poll_wait()
之前,發生中斷並完成wake_up_interruptible()
。
現在執行poll_wait()
。
如果沒有進一步的中斷, poll()
調用是否有可能永遠被阻塞?
我看到該進程在輪詢文件操作中被
poll_wait()
置於睡眠狀態......
不,你弄錯了。
調用poll_wait
只是將當前進程的狀態設置為不可運行,並將當前進程添加到等待隊列中。 這兩個操作都是非睡眠的,所以poll_wait
返回。 之后, poll
文件操作一直持續到結束並返回可用操作的掩碼。
文件poll
操作的調用者將調用schedule()
並將當前進程置於睡眠狀態。 但是schedule()
只有在返回可用操作的掩碼沒有攔截請求操作的掩碼時才會被調用。
如您所見,poll 方法首先調用poll_wait
,然后才計算掩碼:
poll_wait(filep, &idev->wait, wait);
if (listener->event_count != atomic_read(&idev->event))
return EPOLLIN | EPOLLRDNORM;
return 0;
因此,如果在wake_up_interruptible
之前調用poll_wait
,則操作返回( EPOLLIN | EPOLLRDNORM
),並且不會執行睡眠(以防輪詢文件以進行讀取)。
如果在wake_up_interruptible
之后調用poll_wait
,它會將進程返回到可運行狀態,因此schedule()
不會將其置於睡眠狀態。 在調用schedule()
,輪詢操作將重新運行,並且此時它返回非零掩碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.