C语言中的进程和无限循环用于Linux

这是我想要做的:

编写一个带有整数命令行参数n的C程序,生成n个进程,每个进程生成-100到100之间的随机数,然后计算并打印出这些随机数的总和。 每个进程都需要打印出它生成的随机数。

这是我到目前为止:

#include  #include  #include  #include  #include  #include  #include  int main(int argc, char *argv[]){ int command,processCheck; // processCheck: to check if fork was successful or not and to char * strNumProcess = NULL;// check the status of child process while((command = getopt(argc, argv, "n:"))!=-1){ if(command == 'n'){ strNumProcess = optarg; break; } } int numProcess = atoi(strNumProcess); int pipes[numProcess][2]; int randomNum; // Variable to store the random number int randomNumSum=0; // Initialized variable to store the sum of random number /** A loop that creates specified number of processes**/ for(int i=0; i<numProcess; i++){ processCheck = fork(); // creates a child process. Usually fork() = 2^n processes if(processCheck < 0){ // Checks for the error in fork() printf("Error"); exit(1); // Terminates with error } else if(processCheck == 0){ close(pipes[i][0]); /** Child process**/ srand(time(NULL)+getpid()); // sets the randomness of the number associted with process id randomNum = rand()% 201 + (-100); // sets the range of random number from -100 to 100 and stores the random number in randomNum printf("%d\n" , randomNum); // Prints out the random number write(pipes[i][1], &randomNum, sizeof randomNum); close(pipes[i][1]); exit(0);// Terminates successfully } else{ if(wait(NULL)){ // Waits for the child process to end and directs to parent process int v; if(read(pipes[i][0], &v, sizeof v)==sizeof(v)){ randomNumSum+=v; close(pipes[i][0]); } } } close(pipes[i][1]); } printf("%d\n", randomNumSum); // Prints the sum of the random number return 0; } 

程序在第二个过程后进入无限循环。

我鼓励你再次仔细阅读我的回答 。 我已经为您提供了2个运行示例,您只需要在代码中导入技术。

因此,您希望将解决方案与管道一起使用,然后再次阅读答案中的代码。 看看在我做fork之前,我做了这个:

 if(pipe(pipes[i]) == -1) { perror("pipe"); pids[i] = -2; // used later for error checking continue; } 

这会创建管道,您省略了代码中非常重要的部分。 没有它, pipes[i]将是未初始化的,并且使用closereadwrite未初始化的文件描述符是未定义的行为,任何事情都可能发生:崩溃,infinte循环等。

孩子的部分还可以,父母的部分不是那么多。 删除else父部分的代码,并将其放在for循环之外,就像我一样。 你正在分叉并立即等待孩子结束。 只有在前一个童工结束之后,无论如何顺序启动多个童工时,有什么意义? 为什么要用fork呢?

拥有童工的关键在于你一次性启动它们,以便它们同时运行并完成工作。 这就是为什么父进程中的wait阶段应该创建并启动所有子工作者之后

同样在父块中你正在close(pipes[i][0]); 这是正确的,但然后在if-then块的末尾,你再次关闭它。 您不能两次关闭文件描述符。

另外我解释了为什么在这种情况下使用waitpid更可靠,使用它。 您还必须确保童工正常退出。 我知道在这个简单的例子中这是真的,但是在较大的例子中,童工可能会使用exec来调用其他进程,你必须确保为了从管道中读取一个正确的值,这个孩子已经正常结束了。 这是父母期望的行为。

所以看起来应该是这样的:

 // save ALL pids of the children! pid_t pids[numProcess]; for(int i=0; i