- 論壇徽章:
- 0
|
當(dāng)一個(gè)進(jìn)程睡眠, 它這樣做以期望某些條件在以后會(huì)成真.任何睡眠的進(jìn)程必須在它再次醒來時(shí)檢查來確保它在等待的條件真正為真. 最常用的函數(shù)為:
wait_event_interruptible(queue, condition)
其中queue 是要用的等待隊(duì)列頭. 注意它是"通過值"傳遞的. 條件是一個(gè)被這個(gè)宏在睡眠前后所求值的任意的布爾表達(dá)式; 直到條件求值為真值, 進(jìn)程繼續(xù)睡眠。
睡眠**的函數(shù)為:
void wake_up_interruptible(wait_queue_head_t *queue);
通過視頻中將到的代碼可以看出,使用了wait_event_interruptible()后,測試程序使用while循環(huán)讀取按鍵狀態(tài)也不會(huì)占據(jù)99%的CPU資源了, 進(jìn)程會(huì)在條件不滿足時(shí)進(jìn)入睡眠,知道按鍵按下后,由wake_up_interruptible() **。
同步的另一種方法是使用select、poll機(jī)制。它是一種非阻塞 I/O 的應(yīng)用程序常常使用的機(jī)制。 poll, select 和 epoll 本質(zhì)上有相同的功能: 每個(gè)允許一個(gè)進(jìn)程來決定它是否可讀或者寫一個(gè)或多個(gè)文件而不阻塞。file_operations結(jié)構(gòu)體中poll的原型為:
unsigned int (*poll) (struct file *filp, poll_table *wait); 函數(shù)主要的作用就是為用戶空間的poll、select提供一個(gè)系統(tǒng)調(diào)用。最后返回一個(gè)mask。
視頻中poll的代碼很簡單,主要使用了poll_wait ()函數(shù)。
void poll_wait (struct file *, wait_queue_head_t *, poll_table *);
用戶空間在調(diào)用poll前設(shè)置了struct pollfd fds[1];通過對fd和events參數(shù)的指定,使得在fd發(fā)生了events指定的條件后**。最后判斷ev_press是否按下,并返回位掩碼。應(yīng)用程序通過返回值是否為0判斷是否需要讀取按鍵狀態(tài)。
視頻還講了一種異步的方法讀取按鍵值。file_operations結(jié)構(gòu)體中fasync原型為:
int(*fasync) (int fd, struct file *filp, int on)
驅(qū)動(dòng)程序需要在該函數(shù)中通過fasync_helper()實(shí)現(xiàn)。fasync_helper 被調(diào)用來從相關(guān)的進(jìn)程列表中添加或去除入口項(xiàng), 當(dāng) FASYNC 標(biāo)志因一個(gè)打開文件而改變。它的所有參數(shù)除了最后一個(gè), 都被提供給 fasync 方 法并且被直接傳遞。當(dāng)數(shù)據(jù)到達(dá)時(shí) kill_fasync 被用來通知相關(guān)的進(jìn)程。它的 參數(shù)是被傳遞的信號(hào)(常常是 SIGIO) 和 band, 這幾乎都是 POLL_IN。
中斷觸發(fā)后通過kill_fasync()來**進(jìn)程。應(yīng)用程序中signal設(shè)置信號(hào),fcntl設(shè)置FASYNC標(biāo)志位。 |
|