在所有子进程终止后,不能运行父进程

cant run parent process after all child processes have been terminated.

本文关键字:不能 运行 进程 子进程 终止      更新时间:2023-10-16

我有一个程序,在创建几个fork()循环后,在父进程之后执行所有子进程。而是在每个子进程终止之前运行父进程。

im childprocess : 18389
parent process done
im childprocess : 18390
parent process done
im childprocess : 18391
parent process done
下面是我如何使用fork()调用 的代码
for (int file = 0; file < files_count; file++) {
        pid_t pid = fork();
        int file_loc = file + 2;
        if (pid == 0) {
            // child process
            occurrences_in_file(argv[file_loc], argv[1]);
            break;
        } else if (pid > 0) {
            // parent process
            parentProcess();
        } else {
            // fork failed
            printf("fork() failed!n");
            return 1;
        }
    }

.

void occurrences_in_file(const std::string& filename_,
        const std::string& pattern_);
void occurrences_in_file(const std::string& filename_,
        const std::string& pattern_) {
    int my_pid;


    cout << "im childprocess : " <<  my_pid <<endl;
}

.

void parentProcess();
void parentProcess() {
    while (true) {
        int status;
        pid_t done = wait(&status);
        if (done == -1) {
            if (errno == ECHILD){
                cout << "parent process done"<< endl;
                break; // no more child processes
            }
        } else {
            if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
                std::cerr << "pid " << done << " failed" << endl;
                _exit(1);
            }
        }
    }

}

在这里,您在循环的每个迭代中创建一个子进程,然后在同一迭代中等待它。因此,在一次迭代结束时,创建了一个子进程,它打印然后退出,父进程从等待中唤醒并打印,因此您得到了前两行。

类似的输出跟随下一个迭代,因此你得到两行循环的每次迭代,它看起来像父在子之前执行,但它不是。

如果你想在所有子进程完成后调用父进程,那么执行以下操作。

引入全局变量isParent,如果当前进程是父进程,该变量为true。初始化为0

int isParent = 0;

则在循环中,不调用parentProcess(),将isParent设置为1

for (int file = 0; file < files_count; file++) {
    pid_t pid = fork();
    int file_loc = file + 2;
    if (pid == 0) {
        // child process
        occurrences_in_file(argv[file_loc], argv[1]);
        break;
    } else if (pid > 0) {
        // parent process
        isParent = 1;
    } else {
        // fork failed
        printf("fork() failed!n");
        return 1;
    }
}

如果设置了isParent,则在for循环之后调用parentProcess

if(isParent){
    ParentProcess(files_count)
}

然后在parentProcess(int numChildren)调用中等待所有子进程。

void parentProcess(int numChildren);
void parentProcess(int numChildren) {
while (true) {
    int status;
    int i;
    for(i = 0;i < numChildren; i++){
        pid_t done = wait(&status);
        if (done == -1) {
            if (errno == ECHILD){
                cout << "parent process done"<< endl;
                break; // no more child processes
            }
        } else {
            if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
                std::cerr << "pid " << done << " failed" << endl;
                _exit(1);
            }
        }
    }   
}