EINTR錯誤的產生:當阻塞於某個慢系統調用的一個進程捕獲某個信號且相應信號處理函數返回時,該系統調用可能返回一個EINTR錯誤。例如:在socket服務器端,設置了信號捕獲機制,有子進程,當在父進程阻塞於慢系統調用時由父進程捕獲到了一個有效信號時,內核會致使accept返回一個EINTR錯誤(被中斷的系統調用)。
當碰到EINTR錯誤的時候,可以採取有一些可以重啓的系統調用要進行重啓,而對於有一些系統調用是不能夠重啓的。例如:accept、read、write、select、和open之類的函數來說,是可以進行重啓的。不過對於套接字編程中的connect函數我們是不能重啓的,若connect函數返回一個EINTR錯誤的時候,我們不能再次調用它,否則將立即返回一個錯誤。針對connect不能重啓的處理方法是,必須調用select來等待連接完成。
注意read()如果讀到數據爲0,那麼就表示文件結束了,如果在讀的過程中遇到了中斷那麼會返回-1,同時置errno爲EINTR。
因此判斷read的條件:
如果read返回<=0
如果==0
表示文件結束, 處理
如果<0 && errno==EINTR
表示中斷,處理
否則,出錯
但是write()如果寫入的數據爲0,那麼就表示出錯,也就是無法寫入了,而如果在寫的過程中遇到了中斷,那麼write()會返回-1,同時置errno爲EINTR。
因此判斷write是否成功時,條件是write返回的結果是否<=0
if<=0
{
if<0
{
if errno==EINTR
那麼重試
else
錯誤處理
}
if ==0
break;
}
ssize_t write(int fd,const void *buf,size_t nbytes)
write函數將buf中的nbytes字節內容寫入文件描述符fd。成功時返回寫的字節數,失敗時返回-1,並設置errno變量。
在網絡程序中,當我們向套接字文件描述符寫時有倆種可能:
1) write的返回值大於0,表示寫了部分或者是全部的數據;
2) 返回的值小於0,此時出現了錯誤,我們要根據錯誤類型來處理。
如果錯誤爲EINTR表示在寫的時候出現了中斷錯誤。如果爲EPIPE表示網絡連接出現了問題(對方已經關閉了連接)。
讀函數read
ssize_t read(int fd,void *buf,size_t nbyte)
read函數是負責從fd中讀取內容。當讀成功時,read返回實際所讀的字節數。如果返回的值是0,表示已經讀到文件的結束了。小於0表示出現了錯誤。如果錯誤爲EINTR說明讀是由中斷引起的,如果是ECONNREST表示網絡連接出了問題。