我需要创建一个程序来创建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");
}
}
答案 0 :(得分:2)
在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创建的大小 - 并打印状态处理程序外的信息。
此外,按照目前的结构,您的父母可以在收获所有孩子之前结束。为子项添加一个计数器,以便在父项退出之前等待所有这些计数器。
答案 1 :(得分:0)
查看信号SIGCHLD
。如果您将其阻止,则必须取消阻止,或者可以明确检查它。
答案 2 :(得分: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.");
}