一、什麼是Interrupted System Call
Interrupted system call 是指在系統調用(system call)過程中,收到來自外部世界的信號(signal)而中斷所造成的返回值問題。
一般來說,系統調用會阻塞等待內核處理完指令再返回結果。如果在處理過程中被信號中斷,執行流(execution flow)會跳轉到信號處理函數(signal handler)處處理信號,直到處理完畢才又返回系統調用。這時候,如果不進行特殊的處理,系統調用的返回值便會變成 EINTR(Interrupted system call)。
二、為什麼會發生Interrupted System Call
Interrupted system call 的發生與操作系統的信號處理機制有關係。當操作系統接收到一個信號時,會在執行流正在執行的上下文處使其轉而執行信號處理函數,待處理完成後再返回原來的執行流。當處理器執行到系統調用時,若此時有信號到來,則會引起剛才所述的跳轉,也就是Interrupted system call。常見的可以觸發 Interrupted system call 的信號包括:SIGALRM、SIGINT、SIGKILL等。
三、如何處理Interrupted System Call
一些阻塞系統調用在 EINTR 返回值出現時會進行自動重啟(automatic restart),而有些則不會。這導致了多種處理 Interrupted system call 的方法:
1.在 EINTR 發生時進行自動重啟
fd_set readfds; int val = select(maxfd+1, &readfds, NULL, NULL, NULL); while(val == -1 && errno == EINTR) { val = select(maxfd+1, &readfds, NULL, NULL, NULL); }
2.使用 sigaction 設置系統調用信號處理程序,使得系統調用能夠在被中斷後重新執行而不產生 EINTR。
struct sigaction new_action, old_action; new_action.sa_handler = my_sigchld_handler; sigemptyset(&new_action.sa_mask); new_action.sa_flags = 0; sigaction(SIGINT, NULL, &old_action); if (old_action.sa_handler != SIG_IGN) sigaction(SIGINT, &new_action, NULL);
3.使用慢系統調用,如:accept、read、write等。這些系統調用可以保證在阻塞等待時收到信號不會造成 hard interrupt 的問題。例如:
ssize_t nbytes; while ((nbytes = read(fd, ptr, length)) == -1 && errno == EINTR) ;
四、Interrupted System Call的影響
在調用特定的系統調用時,如果沒有正確處理 Interrupted system call,將會對程序的正確性和穩定性產生很大的影響。常見的表現會是程序不響應、程序死鎖、資源泄漏等一系列問題。
舉個例子:在使用 select 等待 I/O 事件的時候,如果不考慮 Interrupted System Call,可能會導致進程對 I/O 事件的失去響應,最終表現為網路套接字長時間不被讀寫,應用程序看似正常,但內部的連接等長時間處於未處理狀態。
五、Interrupted System Call 發生的問題
出現 Interrupted System Call 的原因是操作系統接收到了一個信號。如果我們忽略 Interrupted System Call 帶來的問題,可能會引起以下幾個主要的問題:
1.防止無限期的等待
如果程序使用阻塞的 I/O,等待永遠執行,程序就永遠不會停止。這就是所謂的「無限期等待」問題。為了防止這種問題出現,需要在工作隊列上進行特殊處理來檢查 I/O 狀態,以便正確處理 Interrupted System Call。
2.崩潰
由於 Interrupted System Call 引起的程序異常可能導致應用程序崩潰。這可能會產生一系列嚴重的問題,包括數據丟失和無法恢復的應用程序錯誤。
3.數據損壞
出現 Interrupted System Call 可能會導致數據損壞問題。由於傳輸過程中數據在進程和內核之間傳遞,如果進程在中斷之前讀取沒完的數據,可能會導致數據的混亂,以至於無法正常處理。
六、小結
Interrupted System Call 是經常出現的問題,我們必須採取適當的措施來規避它。本文介紹了 Interrupted System Call 的原因和影響,以及如何處理它。通過合理的處理 Interrupted System Call 可以使程序更加健壯,提高系統的穩定性。
原創文章,作者:QGSIX,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/316223.html