簡體   English   中英

如何在自己的SIGCHLD處理程序中獲取set進程的PID?

[英]How do I get the PID of a set process in the handler of its own SIGCHLD?

我正在為大學寫一個玩具外殼,我必須在它結束時更新后台進程的狀態。 所以我提出了讓SIGCHLD的處理程序這樣做的想法,因為該信號是在進程結束時發送的。 問題是,為了實現命令jobs ,我必須將狀態從“運行”更新為“終止”,首先我必須在我專用的數組中找到特定的進程,並且有一種方法可以實現是通過pid搜索,因為數組存儲在jobs顯示的信息。 每個條目都存儲進程pid,狀態(字符串)和命令本身。

現在的問題是:有沒有辦法獲得在信號結束時調用信號的過程的pid?

現在這是我的處理程序函數的樣子:

void handler(int sig){
    int child_pid;
    child_pid = wait(NULL);
    //finds the process with a pid identical 
    //to child_pid in the list and updates its status
    ...
}

由於wait(NULL)返回自調用以來結束的第一個進程的pid,因此僅在另一個后台進程結束時更新狀態,因此更新了錯誤的進程狀態。

除了等待進程結束之外,我們還沒有從wait()waitpid()函數中獲取很多東西,因此任何洞察都可能有所幫助。

雖然在信號處理程序中使用wait不是一個好主意,但您可以執行以下操作來完成您要執行的操作。

void handler(int sig){
    int child_pid;
    int status;

    child_pid = waitpid(-1, &status, WUNTRACED | WNOHANG);
    if(child_pid > 0)
    {
        // your code
        // make sure to deal with the cases of child_pid < 0 and child_pid == 0
    }

}

你在做什么在技術上並沒有錯,但是,使用waitpid會更好。 當你使用waitpid(-1,...)它的工作方式類似於你使用wait(...)並且不僅等待指定的進程而是等待任何終止的進程。 主要區別在於您可以指定WUNTRACED ,它將暫停執行,直到等待集中的進程終止或停止為止。 WNOHANG將告訴waitpid不要暫停執行該流程。 您不希望暫停處理程序。

如果多個信號被發送到同一個進程,即由於多個子節點同時終止,那么似乎只發送了一個信號,因為信號處理程序不會再次執行。 這是由於信號的發送方式; 當一個信號被創建時,它被放入一個異常表中,然后進程“接收”它; 信號不使用隊列。 為了解決這個問題,你需要迭代waitpid(-1,...)調用,直到它返回0,以確保你收獲所有被終止的子節點。

另外,請注意你收獲孩子的其他地方(請注意,如果孩子已經被收獲,那么如果你使用WNOHANG旗子, waitpid將返回0)。 我認為這是導致您看到的狀態僅在另一個后台進程結束時更新的原因。 例如,因為你正在制作一個玩具外殼,我假設你正在等待某個地方的前台進程,如果你在那里以及你的處理程序中使用wait函數,你可以得到兩件事中的一件。 孩子在'等待前台進程'方法中獲得收益,然后當執行處理程序時,沒有任何東西可以收獲。 2,孩子在處理程序方法中獲得收益,然后'等待前台進程'永遠不會退出。

暫無
暫無

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

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