最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Linux使用waitpid回收多個(gè)子進(jìn)程的方法小結(jié)

 更新時(shí)間:2025年11月10日 09:43:22   作者:郝學(xué)勝-神的一滴  
在Unix/Linux系統(tǒng)中,創(chuàng)建子進(jìn)程后,父進(jìn)程需要負(fù)責(zé)回收這些子進(jìn)程的資源,否則會(huì)導(dǎo)致"僵尸進(jìn)程"的產(chǎn)生,本文將詳細(xì)介紹如何使用waitpid系統(tǒng)調(diào)用有效地回收多個(gè)子進(jìn)程,需要的朋友可以參考下

什么是waitpid

waitpid是Unix/Linux系統(tǒng)提供的一個(gè)系統(tǒng)調(diào)用,用于等待子進(jìn)程的狀態(tài)改變并回收其資源。相比于wait函數(shù),waitpid提供了更靈活的控制選項(xiàng),可以指定等待哪個(gè)特定的子進(jìn)程,以及是否阻塞等待【1†source】。

#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *status, int options);

參數(shù)說明:

pid: 要等待的子進(jìn)程ID。特殊值包括:

  • -1: 等待任意子進(jìn)程
  • 0: 等待與調(diào)用進(jìn)程同組的任意子進(jìn)程

0: 等待指定PID的子進(jìn)程

  • status: 用于存儲(chǔ)子進(jìn)程退出狀態(tài)的指針
  • options: 控制選項(xiàng),最常用的是WNOHANG,表示非阻塞模式

回收多個(gè)子進(jìn)程的方法

方法一:循環(huán)調(diào)用waitpid

最簡(jiǎn)單的方法是在父進(jìn)程中循環(huán)調(diào)用waitpid,直到所有子進(jìn)程都被回收:

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

int main() {
    pid_t pids[5];
    int i;
    
    // 創(chuàng)建5個(gè)子進(jìn)程
    for (i = 0; i < 5; i++) {
        pids[i] = fork();
        if (pids[i] == 0) {
            // 子進(jìn)程代碼
            printf("Child process %d started\n", getpid());
            sleep(1 + rand() % 3); // 隨機(jī)休眠1-3秒
            printf("Child process %d exiting\n", getpid());
            exit(0);
        }
    }
    
    // 父進(jìn)程回收子進(jìn)程
    int status;
    pid_t pid;
    
    for (i = 0; i < 5; i++) {
        pid = waitpid(pids[i], &status, 0);
        if (pid == -1) {
            perror("waitpid");
            exit(1);
        }
        printf("Parent reaped child %d\n", pid);
    }
    
    return 0;
}

方法二:非阻塞方式回收子進(jìn)程

使用WNOHANG選項(xiàng),父進(jìn)程可以在不阻塞的情況下檢查子進(jìn)程狀態(tài):

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

int main() {
    pid_t pids[5];
    int i;
    
    // 創(chuàng)建5個(gè)子進(jìn)程
    for (i = 0; i < 5; i++) {
        pids[i] = fork();
        if (pids[i] == 0) {
            // 子進(jìn)程代碼
            printf("Child process %d started\n", getpid());
            sleep(1 + rand() % 3); // 隨機(jī)休眠1-3秒
            printf("Child process %d exiting\n", getpid());
            exit(0);
        }
    }
    
    // 父進(jìn)程非阻塞方式回收子進(jìn)程
    int status;
    pid_t pid;
    int children_left = 5;
    
    while (children_left > 0) {
        pid = waitpid(-1, &status, WNOHANG);
        
        if (pid > 0) {
            // 成功回收一個(gè)子進(jìn)程
            printf("Parent reaped child %d\n", pid);
            children_left--;
        } else if (pid == 0) {
            // 有子進(jìn)程仍在運(yùn)行
            printf("Waiting for children to finish...\n");
            sleep(1);
        } else {
            // 出錯(cuò)
            perror("waitpid");
            exit(1);
        }
    }
    
    printf("All children have been reaped\n");
    return 0;
}

方法三:信號(hào)處理方式回收子進(jìn)程

可以通過SIGCHLD信號(hào)來(lái)通知父進(jìn)程子進(jìn)程已經(jīng)終止,然后在信號(hào)處理函數(shù)中回收子進(jìn)程:

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

void sigchld_handler(int sig) {
    int status;
    pid_t pid;
    
    // 回收所有已終止的子進(jìn)程
    while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
        printf("Parent reaped child %d\n", pid);
    }
}

int main() {
    pid_t pids[5];
    int i;
    
    // 設(shè)置SIGCHLD信號(hào)處理
    struct sigaction sa;
    sa.sa_handler = sigchld_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
    if (sigaction(SIGCHLD, &sa, NULL) == -1) {
        perror("sigaction");
        exit(1);
    }
    
    // 創(chuàng)建5個(gè)子進(jìn)程
    for (i = 0; i < 5; i++) {
        pids[i] = fork();
        if (pids[i] == 0) {
            // 子進(jìn)程代碼
            printf("Child process %d started\n", getpid());
            sleep(1 + rand() % 3); // 隨機(jī)休眠1-3秒
            printf("Child process %d exiting\n", getpid());
            exit(0);
        }
    }
    
    // 父進(jìn)程繼續(xù)執(zhí)行其他任務(wù)
    printf("Parent doing other work...\n");
    sleep(5);
    printf("Parent finished\n");
    
    return 0;
}

最佳實(shí)踐和注意事項(xiàng)

  1. 及時(shí)回收子進(jìn)程:父進(jìn)程應(yīng)該及時(shí)回收子進(jìn)程,避免僵尸進(jìn)程的產(chǎn)生【2†source】。
  2. 處理異常情況:在調(diào)用waitpid時(shí),應(yīng)該檢查返回值,處理可能的錯(cuò)誤情況。
  3. 信號(hào)處理注意事項(xiàng):使用信號(hào)處理方式回收子進(jìn)程時(shí),需要注意信號(hào)處理函數(shù)的可重入性和安全性。
  4. 避免競(jìng)爭(zhēng)條件:在多線程環(huán)境中使用waitpid時(shí),需要注意同步問題,避免競(jìng)爭(zhēng)條件。
  5. 使用WNOHANG:對(duì)于需要同時(shí)處理多個(gè)任務(wù)的父進(jìn)程,使用WNOHANG選項(xiàng)可以避免阻塞,提高程序的響應(yīng)性【3†source】。

總結(jié)

waitpid是Unix/Linux系統(tǒng)中回收子進(jìn)程的強(qiáng)大工具,通過合理使用waitpid及其選項(xiàng),父進(jìn)程可以有效地管理多個(gè)子進(jìn)程。本文介紹了三種常見的回收多個(gè)子進(jìn)程的方法,包括循環(huán)調(diào)用、非阻塞方式和信號(hào)處理方式,并提供了相應(yīng)的代碼示例。根據(jù)具體的應(yīng)用場(chǎng)景和需求,選擇最適合的方法來(lái)管理子進(jìn)程,可以提高程序的健壯性和效率。

在實(shí)際開發(fā)中,還需要考慮程序的錯(cuò)誤處理、資源釋放和信號(hào)安全等問題,確保程序在各種情況下都能正確運(yùn)行。

以上就是Linux使用waitpid回收多個(gè)子進(jìn)程的方法小結(jié)的詳細(xì)內(nèi)容,更多關(guān)于Linux waitpid回收多個(gè)子進(jìn)程的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論

永兴县| 兴业县| 铁岭市| 崇信县| 休宁县| 芒康县| 西和县| 长海县| 克山县| 和林格尔县| 中西区| 安龙县| 宁夏| 五常市| 阿克苏市| 商南县| 万载县| 望城县| 镇平县| 碌曲县| 平安县| 丰台区| 米脂县| 陆川县| 凤台县| 宁波市| 兰坪| 凌海市| 中江县| 肇东市| 乌拉特前旗| 定陶县| 呼伦贝尔市| 广德县| 望江县| 闸北区| 仁怀市| 韶关市| 福州市| 本溪市| 于田县|