我有一个生成随机数n的程序,然后循环n次。
在每次迭代中,它随机化sleeptime
的值,并调用fork。子进程休眠sleeptime
秒,然后使用索引变量的值退出。
然后父进程再次循环,等待每个进程终止。当每个进程终止时,我正在尝试注销进程的pid和childid,但这就是我遇到麻烦的地方。 pids按顺序打印,childid保持为0。
我做错了什么?
int main(int argc, char* argv[])
{
// Wire up the timer
long time = elapsedTime(0);
/* Generate a random number between MINFORKS and MAXFORKS
*/
unsigned int seed = generateSeed(0);
int n = rand_r(&seed) % MAXFORKS + MINFORKS-1;
/* Log next step
*/
time = elapsedTime(1);
printf("%li: Number of forks = %i\n", time, n);
/* Hang on to the PIDs so we can wait for them after forking
*/
pid_t *PIDs = (pid_t *)(malloc(sizeof(*PIDs)*n));
/* Fork n times
*/
for (int i = 0; i < n ; i++)
{
/* Call fork() and retain the returned identifier
*/
pid_t processIdentifier = fork();
/* Randomize the child sleep time
*/
seed = generateSeed(0);
int sleeptime = rand_r(&seed) % MAXPAUSE + MINPAUSE;
/* Check for errors
*/
if (processIdentifier == -1) {
printf("Error: %i", errno);
}
if (!processIdentifier)
{
/* We're in the child process,
* sleep and then exit with
* i as the error code.
*/
usleep(sleeptime);
_exit(i);
}
else
{
/* We're in the parent:
* Store the PID and
* print out the results.
*/
PIDs[i] = processIdentifier;
time = elapsedTime(1);
printf("%li: Child %i, pid = %i, forked, waits %i usec\n", time, i, processIdentifier, sleeptime);
}
}
/* Log next step
*/
time = elapsedTime(1);
printf("%li: Finished forking, going to wait.\n", time);
/*
* Loop through the processes and wait for them
* to terminate. Then print the childid, and the
* the pid.
*/
for (int i = 0; i < n; i++)
{
/* Get the PID we want to track
*/
pid_t pid = PIDs[i];
/* Wait for the child process
* and grab it's status info
*/
int status = NULL;
waitpid(pid, &status, 0);
int childid = -1;
if(WIFEXITED(status))
{
childid = WTERMSIG(status);
}
/* Log the results
*/
time = elapsedTime(1);
printf("%li: Child %i, pid = %i, terminated\n", time, childid, pid);
}
/* All done!
*/
time = elapsedTime(1);
printf("All done. It only took %li milliseconds!", time);
}
免责声明,这是作业(link here, may disappear at any time),但我已经完成了几乎全部工作。我只是很难理解它的这一方面。
答案 0 :(得分:4)
您的代码正在按照您在后续waitpid()
来电中提供的顺序等待pid。如果您将-1
作为第一个参数传递给waitpid()
(或者只是调用wait()
),您将获得内核通知您的第一个子项,而不是一个你特意要求得到通知。检查返回值以查看它是哪个子项(或者是否发生错误)。
childid
保留0
,因为您正在从等待状态中提取WTERMSIG
,而不是WEXITSTATUS
。
答案 1 :(得分:2)
for (int i = 0; i < n; i++)
{
pid_t pid = PIDs[i];
int status = NULL;
waitpid(pid, &status, 0);
首先,它等待第一个进程结束,然后打印该进程的信息 然后它等待第二个进程结束,然后打印该进程的信息 然后它等待第三个过程结束......
你想知道他们为什么被按顺序报道?
将-1传递给waitpid
,而this page表示将等待任何子线程而不是特定线程。
此外,在打印之前,您有int childid = -1;
。不知道为什么。