执行后台进程并检查父进程的状态

时间:2014-10-31 20:47:08

标签: c background exec fork pid

我目前正在尝试:

  1. 使用fork()调用和子控件中的execvp()执行后台进程。
  2. 如果对execvp()的调用成功,则将子进程的PID添加到列表中。
  3. 如果对execvp()的调用返回-1(错误),请不要将PID添加到列表中。
  4. 我的问题是:如果execvp()返回-1(例如,如果找不到可执行文件)我无法与父进程“通信”,因为我在fork()中的子进程内。如果我使用waitpid()等待孩子,我没有运行后台进程(因为我失去了并发性)。

    我尝试使用WNOHANG并检查*状态(WEXITSTATUS(状态)== 1)但是它不起作用(因为父进程“立即”执行并且不知道孩子是否已经退出,或者那是我的想法)

    我目前的代码:

    void background(char *vector[]) {
    pid_t childp;
    int status;
    childp=fork();
        if (childp==-1){ 
            perror("Error using fork \n");
            return;
        }
        if (childp==0) { //Child process
            if (execvp(vector[0],vector)==-1) {
                perror("exec");
                exit(1);
            }
        }
    waitpid(-1, &status, WNOHANG);
    if(WIFEXITED(status)) {
        //Child exited
        if (WEXITSTATUS(status) == 1) {
            //Child exited with error
            return;
        }
    }
    if (insertProcess(childp,vector)==-1)
        perror("Full list");
    else
        updateList();   
    }
    

    我目前发现的唯一解决方案是在waitpid之前插入一个sleep(1)调用(来源:https://stackoverflow.com/a/26617152/1339354),但这看起来更像是黑客而不是做得好。还有其他想法吗?

1 个答案:

答案 0 :(得分:0)

如果您在WNOHANG中使用waitpid(),请务必指定子进程。如果不这样做,waitpid()将返回最后一个孩子的状态。

我不确定您是否正在尝试将所有成功的流程保存在列表中。如果你正在尝试它,为什么不总是instert,然后删除他们死的过程?控制信号SIGCHLD。在那里,使用waitpid来查看死亡过程并将其删除在列表中。只需在创建过程时停用信号SIGCHLD,将过程插入列表,然后再次激活信号。