2014-04-08 74 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."); 
}