2012-03-06 40 views
23

我正在學習編寫linux設備驅動程序的阻塞I/O函數,我想知道ERESTARTSYS的用法是什麼。考慮以下幾點:ERESTARTSYS在編寫linux驅動程序時使用了什麼?

全局變量:

wait_queue_head_t my_wait_q_head; 
int read_avail = 0; 


完Device_Init():

init_waitqueue_head(&my_wait_q_head);


device_read():

printk("I'm inside driver read!\n"); 
wait_event_interruptible(&my_wait_q_head, read_avail != 0); 
printk("I'm awaken!\n"); 


device_write():

read_avail = 1; 
wake_up_interruptible(&my_wait_q_head); 


當我從用戶空間調用read(),命令提示掛起,直到我打電話預期write()如。消息printk也相應地出現在dmesg中。不過,我看到了一些這樣寫的驅動程序:

device_read()的另一個版本:

printk("I'm inside driver read!\n"); 
if(wait_event_interruptible(&my_wait_q_head, read_avail != 0))  
{return -ERESTARTSYS;} 
printk("I'm awaken!\n"); 

我測試使用用戶空間中的相同方法device_read()的第二個版本,並且將結果是完全一樣的,那麼,ERESTARTSYS有什麼用?

P/S:我讀過這本書的Linux設備驅動程序,但我不明白這一點,可有人舉一個例子來eleborate?:

一旦我們把過去的這一號召,東西已經把我們喚醒了,但是我們不知道 是什麼。一種可能是該過程收到信號。如果包含wait_event_interruptible調用的語句包含 ,則檢查 。該聲明確保信號的適當和預期的反應 ,其可能已經負責喚醒 過程(因爲我們處於可中斷睡眠中)。如果信號有 到達,並且它沒有被進程阻塞,那麼適當的 行爲是讓內核的上層處理事件。到 爲此,驅動程序向調用者返回-ERESTARTSYS;該值爲 ,由虛擬文件系統(VFS)層在內部使用, 重新啓動系統調用或返回-EINTR到用戶空間。我們使用 相同類型的檢查來處理每個讀取操作的信號處理以及寫入實現的 。

來源:http://www.makelinux.net/ldd3/chp-6-sect-2

回答

43

-ERESTARTSYS被連接到可重新啓動的系統調用的概念。可重新啓動的系統調用是當內核出現中斷時可以被內核透明地重新執行的系統調用。

例如,睡在系統調用中的用戶空間進程可以獲得一個信號,執行一個處理程序,然後當處理程序返回時,它看起來會回到內核並保持原始系統調用的睡眠狀態。

使用POSIX sigaction API的SA_RESTART標誌,進程可以安排與信號關聯的重新啓動行爲。

在Linux內核中,當在系統調用的上下文中阻塞的驅動程序或其他模塊檢測到任務因信號而被喚醒時,它可以返回-EINTR。但-EINTR會冒泡到用戶空間並導致系統調用返回-1,並將errno設置爲EINTR。

如果您返回-ERESTARTSYS,則意味着您的系統調用是可重新啓動的。 ERESTARTSYS代碼不一定會在用戶空間中看到。它要麼被轉換爲-1返回,並將errno設置爲EINTR(很明顯,在用戶空間中看到),要麼將其轉換爲系統調用重新啓動行爲,這意味着您的系統調用會使用相同的參數再次調用(通過對部分用戶空間進程沒有任何操作:內核通過將信息存儲在特殊的重新啓動塊中來執行此操作)。

請注意上一段中「相同參數」的明顯問題:某些系統調用不能使用相同的參數重新啓動,因爲它們不是冪等的!例如,假設有睡眠呼叫,如納睡,持續5.3秒。它在5秒後中斷。如果它天真地重新開始,它會再睡5.3秒。它必須將新的參數傳遞給重新啓動的呼叫才能休眠0.3秒;即改變重啓塊的內容。有一種方法可以做到這一點:將不同的參數放入任務的重新啓動塊中並使用-ERESTART_RESTARTBLOCK返回值。

解決第二個問題:有什麼區別?爲什麼不直接寫入讀取例程而不檢查返回值並返回-ERESTARTSYS?那麼,因爲喚醒是由信號引起的呢!每當信號到達時,是否要讀取讀取0字節的讀數?這可能會被用戶空間誤解爲數據結束。這種問題不會在不使用信號的測試案例中顯示出來。

+1

@Noge:爲了看清它們之間的區別,在過程調用read()之後,調用write()之前發送一個信號。 – caf 2012-03-06 03:09:15

相關問題