2014-04-08 33 views
0

我需要创建一个程序来创建n个进程并显示信息。当每个过程结束时,我将打印它的PID和退出状态。我做这件事的方式是,父程序等待创建下一个过程,直到当前过程结束。我需要它,以便它可以持续创建子进程,并在有一个进程结束时仅显示出口信息,而不会阻止父进程继续。我可以弄清楚在哪里等待以确保这一点。以下是我的代码:如何不用waitpid阻止父亲

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"); 
     } 
} 
+0

设置SIGCHLD的信号处理程序。在处理程序中调用'wait'。 – Duck

回答

0

调查信号SIGCHLD。如果您将其封锁,则必须解除封锁,否则可能会明确检查。

+0

什么是独立的孩子? – Duck

+0

请参阅Stackoverflow发布[分离与可连接的POSIX线程](http://stackoverflow.com/questions/3756882/detached-vs-joinable-posix-threads)。在这种情况下唯一重要的是它们不会被分离。 – Deduplicator

+0

OP正在创建进程而不是线程。这是无关紧要的。苹果和桔子。 – Duck

1

之前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创建 - 和打印状态处理程序之外的信息。

此外,根据目前的结构,您的父母可以在收获所有孩子之前结束。为孩子添加一个计数器,以便在父母退出前等待所有孩子。

0

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