【问题标题】:cant run parent process after all child processes have been terminated.终止所有子进程后无法运行父进程。
【发布时间】:2015-10-05 11:45:36
【问题描述】:

我有一个程序,它在循环中创建多个 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);
            }
        }

    }


}

【问题讨论】:

    标签: c++ multiprocessing fork


    【解决方案1】:

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

    下一次迭代会出现类似的输出,因此循环的每次迭代都会有两行,看起来父级在子级之前执行,但事实并非如此。

    如果要在所有子进程完成后调用父进程,请执行以下操作。

    如果当前进程是父进程,则引入一个全局变量 isParent 。将其初始化为零

    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);
                }
            }
        }   
    }
    

    【讨论】:

    • 我知道它在它的孩子之后执行。但我尝试的是在所有孩子之后执行它,所以输出看起来像这样: im childprocess : 18389 \n im childprocess : 18390 \n im childprocess : 18391 \n parent process done ...
    • 您编写的代码并没有这样做。正如我所说,这段代码在每次迭代中产生一个新的孩子,父母等待那个孩子完成,然后在下一次迭代中产生另一个孩子。这也是为什么parent process done 被打印三次而不是一次的原因。如果你想调用最后打印的parent process done,然后按照我的编辑
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    相关资源
    最近更新 更多