c - 如何不使用 waitpid 阻止父级

标签 c unix parallel-processing posix child-process

我需要创建一个程序来创建 n 个进程并显示信息。当每个进程结束时,我将打印它的 PID 和退出状态。我这样做的方式是,父程序等待创建下一个进程,直到当前进程结束。我需要它,以便它不断创建子进程,并在一个进程结束时只显示退出信息,而不会阻止父进程继续。我不知道该在哪里等待以确保这一点。下面是我的代码:

int main (int argc, char *argv[])
{
  if (argc < 2)
  {
     printf("\n\nUsage: %s <enter a number (12 or less)>\n\n", argv[0]);
     exit (-1);
  }
  else
  {
    int *processNum = (int *)malloc(sizeof(12));
    int processNumTemp;

    processNumTemp = atoi(argv[1]);
    processNum = &processNumTemp;

  if(*processNum > 12 || *processNum < 1)
    {
      printf("\n\nUsage: %s <enter a number (12 or lrss)>\n\n", argv[0]);
    }
  else
    {
      parentInfo(processNum);
      createChildProcess(processNum);
    }


  }

 return 0;
}


//Name:  parentInfo
//Description:  Displays information about the parent process
//Parameters:  processNum - stores the number of child processes to create
//             (entered at the command line).
//Return:  none
void parentInfo(int *processNum)
{
 printf("Parent process ID:  %d\n", getppid());
 printf("Number of processes to create:  %d\n", *processNum);
}


//Name:  createChildProcess
//Description:  Creates n number of child processes.
//              For each child process, it says its a child process and it
//              displays its PID.
//              After each child process closes, the parent displays info.
//Parameters:  processNum - stores the number of child processes to create
//             (entered at the command line).
//Return:  none
void createChildProcess(int *processNum)
{
 int i;
 int childStatus;
 pid_t childpid;

 /*The for loop will create n number of processes based on the value of            processNum.*/
 for(i = 1; i <= *processNum; i++)
 childpid = fork();

  //Executes if fork didn't work
  if(childpid < 0)
    {
      perror("fork");
      exit(1);
    }

  //Executes if the fork worked
  else if( childpid == 0)
    {
      int pid = getpid();

      //Prints a message and the child processe's PID
      printf("\nHello I am a child process.\n");
      printf("My PID is %d. \n", getpid());

      for(int x = 1; x <= pid; x ++);

      exit(15);
    }

}
      //Executes after the child process has ended
      //Checks the child process's exit status

      waitpid(childpid, &childStatus, WUNTRACED);
      printf("\nPID of the child process that was just created:  %d.\n", childpid);

      if(WIFEXITED(childStatus))
        {
          printf("PID %d exited normally.  Exit number:  %d\n", childpid, WEXITSTATUS(childStatus));
        }
      else if(WIFSTOPPED(childStatus))
        {
          printf("PID %d was stopped by %d\n", childpid, WSTOPSIG(childStatus));
        }
      else if(WIFSIGNALED(childStatus))
        {
          printf("PID %d exited due to signal %d\n.", childpid, WTERMSIG(childStatus));
        }
      else
        {
          perror("waitpid");
        }
}

最佳答案

fork 代码之前

signal(SIGCHLD, childHandler);

在 childHandler 中放入您的 waitpid 代码。

void childHandler(int signum)
{

    pid_t childpid;
    int childstatus;

    while ((childpid = waitpid( -1, &childstatus, WNOHANG)) > 0)
    {
        if (WIFEXITED(childStatus))
        {
            printf("PID %d exited normally.  Exit number:  %d\n", childpid, WEXITSTATUS(childStatus));
        }
        else
            if (WIFSTOPPED(childStatus))
            {
                printf("PID %d was stopped by %d\n", childpid, WSTOPSIG(childStatus));
            }
            else
                if (WIFSIGNALED(childStatus))
                {
                    printf("PID %d exited due to signal %d\n.", childpid, WTERMSIG(childStatus));
                }
                else
                {
                    perror("waitpid");
                }
        }
    }
}

您不应该在信号处理程序中使用诸如 printf 之类的异步不安全调用,因此请更改您的代码以将状态保存在全局或堆分配数组中 - 您知道从 processNum 创建的大小 - 和在处理程序外打印状态信息。

此外,按照目前的结构,您的 parent 可以在收割所有 child 之前结束。为 child 添加一个计数器,以便在 parent 退出之前等待所有 child 。

关于c - 如何不使用 waitpid 阻止父级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22939431/

相关文章:

C:循环从0跳转到1000,因此不循环。为什么?

c - write(2) 仍然报告成功,即使我关闭了套接字

parallel-processing - 为什么摩尔定律需要并行计算?

c - 在 C 中动态声明变量/结构

c - 如何使用正确的参数在 C 中调用 execl()?

linux - 如何在gnuplot中将字符串转换为数字

java - 查找文件,对它们进行 gtar 并创建报告

algorithm - 如何正确地将龙格误差估计规则添加到这个例子中?

c# - Parallel.ForEach 和 DataGridViewRow

c - 变长数组指令是如何生成的?