2016-03-03 66 views
1

我是Linux新手,我正在學習系統調用和信號。例如,read系統調用可以被信號中斷。如果在讀取任何內容之前它被中斷,它會失敗並將errno設置爲EINTR。在glibc這主要是由TEMP_FAILURE_RETRY宏處理。但是,如果僅在讀取某些數據時中斷,則函數將成功讀取小於請求的數據。在這種情況下,調用者應該爲缺失部分發出另一個read,繼續讀取所有數據。儘管如此,glibc源包含無數個電話這樣的:glibc和系統調用被信號中斷

if (TEMP_FAILURE_RETRY (read (fd, &word, 4)) != 4) 
    error (EXIT_FAILURE, errno, _("cannot read header")); 

這似乎意味着它的,在許多地方,無法正常重新啓動系統調用。我錯過了什麼嗎?對我來說,看起來部分讀取中斷的情況似乎比沒有讀取的情況更常見,並且越來越多,因此讀取請求的數量變得更大。

回答

1

但是,如果僅在讀取某些數據時中斷,則函數會成功讀取小於請求的數據。

您對此主題的理解不完整。您需要仔細閱讀此man page(「信號處理程序的系統調用和庫函數中斷」部分)。

特別要注意「慢速」設備和本地磁盤(假設速度很快)之間的區別。

這似乎意味着它在許多地方都沒有正確地重新啓動系統調用。

如果讀取來自「快速」設備並且使用了SA_RESTART,那麼系統調用將自動重新啓動,並且不可能進行部分讀取。

+0

感謝您的回覆,這確實解決了一些問題。我一定要更多地研究它。從Windows開發背景來看,我不得不承認找到* nix的信號/系統調用機制(以及兩者之間的交互)困惑。 – Steve