簡體   English   中英

waitpid()是Linux中的原子操作嗎?

[英]Is waitpid() an atomic operation in Linux?

例如,在父進程中,我分叉子進程並等待子進程:

int main() {
     setSignal(SIGCHLD, sigchld_handler)
     while(1) {
        // fork some child processes
        myForkFunction()

        waitpid(-1, &status, 0)
     }
}

此外,我有一個SIGCHLD信號處理程序:

void
sigchld_handler(int sig) {
    while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
       // Reap zombie processes
    }    
}

可以看出, waitpid()出現在main()函數和sigchld_handler()函數中。 我想知道SIGCHLD是否可以中斷waitpid 如果它可以被SIGCHLD打斷,那會發生什么?

有沒有人對此有任何想法?

waitpid()的POSIX規范部分說明:

如果定義了_POSIX_REALTIME_SIGNALS,並且實現對SIGCHLD信號進行排隊,那么如果由於子進程的狀態可用而返回wait()waitpid() ,則應丟棄與子進程的進程ID關聯的任何掛起的SIGCHLD信號。 任何其他待處理的SIGCHLD信號應保持未決狀態。

否則,如果SIGCHLD被阻止,如果由於子進程的狀態可用而返回wait()waitpid() ,則除非另一個子進程的狀態可用,否則應清除任何未決的SIGCHLD信號。

對於所有其他條件,未指定在傳送SIGCHLD信號時是否可以使用子狀態。

所引用的段落中的第三段似乎意味着你正在踩着薄冰。 它沒有提到“實現定義”或類似 - 未指定意味着標准沒有說明將發生什么,您可能會或可能不會從特定於實現的文檔中獲取任何信息。

POSIX規范中有很多(措辭非常密集)信息。 還有一些例子和理由 - 提到了sigwait()sigwaitinfo() 值得閱讀整個waipid()頁面。 您也應該閱讀有關Signal概念的內容 - 閱讀更加密集。 (其中一天,我也會這樣做 - 當我需要知道以前沒有涉及的信號時。)


你為什么使用WUNTRACED而不是0WNOHANG WUNTRACED是一個非常專業的條件 - POSIX說:

WUNTRACED
pid指定的任何已停止的子進程的狀態,以及自其停止后尚未報告其狀態的狀態,也應報告給請求進程。

類似的評論適用於WCONTINUED 當你需要它們時,這兩個標志很有用,但你很少需要它們。

我建議你通常應該在waitpid()的第三個參數中使用0WNOHANG

是的,從某種意義上說,只有其中一個能夠成功完成特定的子進程; 如果信號處理程序中斷了main中的那個,那么在信號處理程序返回之后,子項將已經被收獲並且main的調用將失敗。

盡管如此,編寫這樣的代碼是不好的做法。 應該有一個地方處理給定子進程的收獲,通常信號處理程序是一個非常糟糕的選擇,因為它是全局的,它必須知道您的程序可能已經完成的所有可能的子進程, 並且有辦法將這些結果傳達給程序的適當部分

相反,它是通常更好地監測通過子進程的終止poll上管/從孩子的過程,只有waitpid ,你知道后,它的終止,或進行阻止waitpid從一個線程,其唯一的工作就是等待孩子。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM