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



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

int main (int argc, char *argv[])
{
  if (argc < 2)
  {
     printf("nnUsage: %s <enter a number (12 or less)>nn", 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("nnUsage: %s <enter a number (12 or lrss)>nn", 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:  %dn", getppid());
 printf("Number of processes to create:  %dn", *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:  %dn", childpid, WEXITSTATUS(childStatus));
        }
      else if(WIFSTOPPED(childStatus))
        {
          printf("PID %d was stopped by %dn", childpid, WSTOPSIG(childStatus));
        }
      else if(WIFSIGNALED(childStatus))
        {
          printf("PID %d exited due to signal %dn.", 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:  %dn", childpid, WEXITSTATUS(childStatus));
        }
        else
            if (WIFSTOPPED(childStatus))
            {
                printf("PID %d was stopped by %dn", childpid, WSTOPSIG(childStatus));
            }
            else
                if (WIFSIGNALED(childStatus))
                {
                    printf("PID %d exited due to signal %dn.", childpid, WTERMSIG(childStatus));
                }
                else
                {
                    perror("waitpid");
                }
        }
    }
}

您不应该在信号处理程序中使用像printf这样的异步不安全调用,因此请更改代码以将状态保存在全局或堆分配的数组中(您知道要从processNum创建的大小),并在处理程序外部打印状态信息。

此外,按照目前的结构,你的父母可能会在收获所有孩子之前结束。为子项添加一个计数器,以便在父项退出之前等待所有子项。

查看信号SIGCHLD。如果您阻止了它,您必须取消阻止它,或者可能会显式检查它。

wait的目的是等待,所以解决问题的方法是首先创建所有子项,然后开始等待它们终止。这里有一个程序可以做到这一点:

// fork
#include <unistd.h>
// wait
#include <sys/types.h>
#include <sys/wait.h>
// exit
#include <stdlib.h>
//printf
#include <stdio.h>
void child( int id)
{
  int seed= id;
  int x= rand_r( &seed) % 10;
  sleep( x);
  exit( x);
}
int main( int argc, char *argv[])
{
  const int n= 5;
  int i;
  printf( "creating %d children.n", n);
  for ( i= 0; i < n; ++i) {
    pid_t pid= fork();
    if ( !pid)
      child( i); // does not return
    else
      printf( "child [0x%x] created.n", pid);
  }
  // all the children are created now
  // now we wait for them to terminate
  printf( "waiting for children to terminate.n", n);
  for ( i= 0; i < n; ++i) {
    int result;
    pid_t pid= wait( &result);
    printf( "child [0x%x] terminated with result [%u].n", pid, WEXITSTATUS( result));
  }
  puts( "all children terminated.");
}

相关内容

  • 没有找到相关文章

最新更新