Linux監聽子線程的函數

來源:互聯網
上載者:User

waitpid系統調用】   
    
功能描述: 
等待進程改變其狀態。所有下面哪些調用都被用於等待子進程狀態的改 變,擷取狀態已改變的子進程資訊。狀態改變可被認為是:1.子進程已終止。2.訊號導致子進程停止執行。3.訊號恢複子進程的執行。在子進程終止的情況 下,wait調用將允許系統釋放與子進程關聯的資源。如果不執行wait,終止了的子進程會停留在"zombie"狀態。

如果發現子進程改變了狀態,這些調用會立即返回。反之,調用會被阻塞直到子進程狀態改變,或者由訊號處理控制代碼所中斷(假如系統調用沒有通過sigaction的SA_RESTART標誌重啟動)。

wait 系統調用掛起當前執行中的進程,直到它的一個子進程終止。waitpid掛起當前進程的執行,直到指定的子進程狀態發生變化。預設,waitpid只等待 終止狀態的子進程,但這種行為可通過選項來改變。waitid系統調用對於等待哪個子進程狀態改變提供了更精確的控制。
  
子進程已終 止,父進程尚未對其執行wait操作,子進程會轉入“僵死”狀態。核心為“僵死”狀態的進程保留最少的資訊量(進程標識,終止狀態,資源使用資訊),過後 父進程執行wait時可以擷取子進程資訊。只要僵死的進程不通過wait從系統中移去,它將會佔據核心進程表中的一個欄位。如果進程表被填滿,核心將不能 再產生新進程。如果父進程已終止,它的僵死子進程將由init進程收養,並自動執行wait將它們移去。

用法:  
#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);

參數:   
pid:可能值有以下

小於-1 //意味著等待所有其進程組標識等於pid絕對值的子進程。
 -1 //意味著等待任何子進程。
 0 //意味著等待任何其組標識等於調用進程組標識的進程。
大於0 //意味著等待其進程標識等於pid的進程。

status:指向子進程的返回狀態,可通過以下宏進行檢索

WIFEXITED(status) //返回真如果子進程正常終止,例如:通過調用exit(),_exit(),或者從main()的return語句返回。
WEXITSTATUS(status) //返回子進程的退出狀態。這應來自子進程調用exit()或_exit()時指定的參數,或者來自main內部return語句參數的最低位元組。只有WIFEXITED返回真時,才應該使用。
WIFSIGNALED(status) //返回真如果子進程由訊號所終止
WTERMSIG(status) //返回導致子進程終止的訊號數量。只有WIFSIGNALED返回真時,才應該使用。
WCOREDUMP(status) //返回真如果子進程導致核心轉存。只有WIFSIGNALED返回真時,才應該使用。並非所有平台都支援這個宏,使用時應放在#ifdef WCOREDUMP ... #endif內部。
WIFSTOPPED(status) //返回真如果訊號導致子進程停止執行。
WSTOPSIG(status) //返回導致子進程停止執行的訊號數量。只有WIFSTOPPED返回真時,才應該使用。
WIFCONTINUED(status) //返回真如果訊號導致子進程繼續執行。

options:可以是0個或多個以下符號常量通過or運算的組合體

WNOHANG //如果沒有子進程退出,立即返回
WUNTRACED //如果有處於停止狀態的進程將導致調用返回。
WCONTINUED //如果停止了的進程由於SIGCONT訊號的到來而繼續運行,調用將返回。

下面是Linux特有的選項,不能用於waitid
__WCLONE //只等待"clone"的子進程。一個"clone" 進程即是終止時不會給父進程發送訊號,或者不會給父進程發送SIGCHLD訊號的進程。
__WALL //等待所有類型的子進程,包括"clone"和"non-clone"。
__WNOTHREAD //不會等待同一線程組的其它線程的子孫。

WUNTRACED 和 WCONTINUED 只有在SIGCHLD訊號沒有設定SA_NOCLDSTOP標誌時才起作用。

idtype,id:這兩個參數結合在一起指出應選擇等待哪些子進程,可能情況有

idtype == P_PID //等待進程標識與id匹配的子進程。
idtype == P_PGID //等待進程組標識與id匹配的任何子進程。
idtype == P_ALL //等待任何子進程,id無作用

可在options參數中指定的感興趣的子進程狀態改變標誌有以下常量,可以通過or運算加以組合

WEXITED //等待已終止的子進程。
WSTOPPED //等待由於訊號已停止執行的子進程。
WCONTINUED //等待由於訊號已恢複執行的子進程。
WNOHANG //作用如同waitpid。
WNOWAIT //保留子進程的可等待狀態,後面的wait調用可再次擷取子進程的狀態資訊。

infop:成功執行返回時,waitid將填充infop所指向結構體的如下欄位

si_pid //子進程標識。
si_uid //子進程的真實使用者標識。
si_signo //總被設定為SIGCHLD。
si_status //子進程的退出狀態,或者導致子進程退出,停止執行或恢複執行的訊號,需要根據si_code欄位來解釋。
si_code //可能值有CLD_EXITED(子進程調用_exit退出), CLD_KILLED(子進程被訊號殺死),CLD_STOPPED(訊號導致子進程停止執行),CLD_CONTINUED(訊號恢複子進程繼續執行)。
    
返回說明:   
wait():成功執行時,返回終止子進程的標識。失敗返回-1;
waitpid():成功執行時,返回狀態改變的子進程標識。失敗返回-1;如果指定WNOHANG標誌,同時pid指定的進程狀態沒有發生變化,將返回0。
waitid():成功執行或者WNOHANG標誌被設定而id指定的子進程狀態沒有發生變化時返回0。失敗返回-1。

出錯值可能有下面這些
ECHILD:參數指定的進程不存在,或者並非調用進程的子進程
EINTR;WNOHANG不被設定,同時捕捉到一個不被阻塞的訊號或SIGCHLD訊號
EINVAL:options參數無效

例子:

$ ./a.out &
Child PID is 32360
[1] 32359
$ kill -STOP 32360
stopped by signal 19
$ kill -CONT 32360
continued
$ kill -TERM 32360
killed by signal 15
[1]+  Done                    ./a.out
$

#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    pid_t cpid, w;
    int status;

    cpid = fork();
    if (cpid == -1) { perror("fork"); exit(EXIT_FAILURE); }

    if (cpid == 0) {            /* 子進程執行 */
        printf("Child PID is %ld/n", (long) getpid());
  if (argc == 1)
            pause();                    /* Wait for signals */
        _exit(atoi(argv[1]));

    } else {                    /* 父進程執行 */
        do {
            w = waitpid(cpid, &status, WUNTRACED | WCONTINUED);
            if (w == -1) { perror("waitpid"); exit(EXIT_FAILURE); }

            if (WIFEXITED(status)) {
                printf("exited, status=%d/n", WEXITSTATUS(status));
            } else if (WIFSIGNALED(status)) {
                printf("killed by signal %d/n", WTERMSIG(status));
            } else if (WIFSTOPPED(status)) {
                printf("stopped by signal %d/n", WSTOPSIG(status));
            } else if (WIFCONTINUED(status)) {
                printf("continued/n");
            }
        } while (!WIFEXITED(status) && !WIFSIGNALED(status));
        exit(EXIT_SUCCESS);
    }

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.