【发布时间】:2013-10-14 18:02:20
【问题描述】:
我正在尝试编写一个程序,根据用户输入值“n”,我将分叉那么多进程以同时运行。此外,每个孩子都试图执行到我创建的另一个文件,这将生成 x 睡眠时间和 x 退出值。最终,当孩子死亡时,父母需要打印 pid 和 exit_status。重要的部分是确保儿童死亡是 x,而不是同时发生。到目前为止,有两件事我无法弄清楚。
- 让我的 execl 运行我的 sleep.c 文件(如下所示)。
- 让孩子们随机分叉和死亡,而不是以有序的方式,结果打印谁死了,他们生成的随机退出状态。
我有两个文件,Sleep.c 和 Ranchild.c。
睡眠.C
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
/* Generated random sleep time, and return random exit value */
int main()
{
/* Calculate A Random Time To Sleep 1 - 10 Seconds*/
srand(time(NULL));
int r = (rand() % 10) + 1;
printf("Sleep Time: %d\n", r);
sleep(r);
/* Calculate A Random Exit Value */
int r2 = (rand() % 30) + 1;
exit(r2);
}
RANCHILD.C
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
int main()
{
/* Get User Input */
int i, n;
printf("Please Enter An Integer!\n");
/* Test User Input */
if(!scanf("%d", &n)) {
printf("Invalid Input!\n");
return -1;
}
/* Initialize Needed Variables */
pid_t pid[n];
int status, exit_status;
for(i = 0; i < n; i++) {
if((pid[i] = fork()) < 0) {
perror("Fork Failed!");
return -2;
}
if(pid[i] == 0) {
execl("sleep", "sleep", (char *)0);
} else {
/* Print Child Results */
if (waitpid(-1, &status, WNOHANG) == 0) {
if(WIFEXITED(status)) {
exit_status = WEXITSTATUS(status);
printf("Exit Status From %d was %d!\n", pid[i], exit_status);
}
}
}
}
exit(0);
}
它永远不会执行到睡眠文件,结果示例如下:
3
Exit Status From 27369 was 0!
Exit Status From 27370 was 0!
Exit Status From 27371 was 0!
Sleep Time: 4
Sleep Time: 4
Sleep Time: 4
非常感谢您的帮助!!
【问题讨论】:
-
在调用
wait之前,您无法检查status的值。我没有看到对wait的呼叫。 -
我加了等待,结果还是0 =[ 可能是我加错了?不管状态如何,孩子们仍在同时死亡。
-
他们正在同时死亡,因为您可能在检查状态的“其他”中等待他们。您将阻止
wait并因此在循环中一次创建一个孩子。 -
在
sleep.c代码中,由于子进程都可能同时启动(同一秒),使用time()播种srand()不太可能正常工作。也使用getpid();保证是唯一的。您还可以使用亚秒计时函数之一(例如clock_gettime()或gettimeofday())结果的亚秒部分。但是在多CPU芯片上,PID还是唯一的,时间也不一定唯一。当然,退出状态也有同样的问题;所有孩子都可能以相同的状态退出。 -
您需要围绕
waitpid()调用而不仅仅是if。并且整个等待工作应该在您创建所有孩子之后完成,而不是在您创建每个孩子之后。