簡體   English   中英

poll_wait() 和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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM