C for Linux中的进程和无限循环
以下是我试图做的: 编写一个接受整数命令行参数n的C程序, 生成n个进程,每个进程将在 -然后计算并打印出这些随机数的总和。每个进程都需要打印出随机数 产生 这就是我到目前为止所做的:C for Linux中的进程和无限循环,c,linux,C,Linux,以下是我试图做的: 编写一个接受整数命令行参数n的C程序, 生成n个进程,每个进程将在 -然后计算并打印出这些随机数的总和。每个进程都需要打印出随机数 产生 这就是我到目前为止所做的: #include <stdio.h> #include <time.h> #include <stdlib.h> #include <getopt.h> #include <sys/types.h> #include <sys/wait.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[]){
int命令,processCheck;//processCheck:检查fork是否成功并
char*strNumProcess=NULL;//检查子进程的状态
while((命令=getopt(argc,argv,“n:)!=-1){
如果(命令=='n'){
strNumProcess=optarg;
打破
}
}
int numProcess=atoi(strNumProcess);
int管道[numProcess][2];
int randomNum;//用于存储随机数的变量
int randomNumSum=0;//初始化变量以存储随机数之和
/**创建指定数量进程的循环**/
对于(inti=0;i我鼓励您再次仔细阅读。我已经提供了
有了两个运行的示例,您所要做的就是将技术导入到您的应用程序中
代码
因此,您希望将解决方案用于管道,然后在
再次回答。请注意,在我执行分叉之前,我执行了以下操作:
if(pipe(pipes[i]) == -1)
{
perror("pipe");
pids[i] = -2; // used later for error checking
continue;
}
这将创建管道,您省略了代码中非常重要的部分。
没有它,pipes[i]
将被取消初始化,并使用close
和read
和
在未初始化的文件描述符上写入
是未定义的行为和任何东西
可能发生:崩溃、infinte循环等
子部件正常,父部件不太正常。删除父部件的代码
在else
中加入一部分,并像我那样将其置于for
循环之外。
你在用叉子叉东西,然后马上等着孩子结束。这是什么
连续启动多个童工的意义
不管怎么说,只有在前一个童工结束之后?那为什么还要用fork
呢
雇用童工的全部意义在于,你可以一次将他们全部解雇
这就是为什么wait
ing阶段进入的原因
父进程应在创建了所有子工作人员并
发射
同样在父块中,您正在执行close(pipes[i][0]);
这是正确的,
但是在if-then
块的末尾,您再次关闭它。您不能关闭它
一个文件描述符两次
我还解释了为什么在这种情况下使用waitpid
更可靠,请使用它
还必须确保童工正常离开。我知道这一点
这是一个平凡的例子,但在较大的例子中,童工
可能使用exec
调用其他进程,您必须确保
从管道中读取一个正确的值,此子项已正常结束。这是
父母期望的行为
所以它应该是这样的:
// save ALL pids of the children!
pid_t pids[numProcess];
for(int i=0; i<numProcess; i++){
// create pipe
if(pipe(pipes[i]) == -1)
{
exit(1); // Terminates with error
}
pids[i] = fork(); // creates a child process. Usually fork() = 2^n processes
if(pids[i] < 0){ // Checks for the error in fork()
printf("Error");
exit(1); // Terminates with error
}
else if(pids[i] == 0){
/** Child process**/
// closing the reading end of the pipe
// child will only write
close(pipes[i][0]);
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);
// closing writing end of pipe
close(pipes[i][1]);
exit(0);// Terminates successfully
}
// PARENT
// closing writing end of pipe
// parent will only read
close(pipes[i][1]);
}
// now that all children have been launched and are running
for(int i=0; i<numProcess; i++){
int status;
if(waitpid(pids[i], &status, 0) == -1)
{
fprintf(stderr, "Cannot wait for child %d with pid: %d\n", i, pids[i]);
continue; // ignoring child
}
if(WIFEXITED(status) && WEXITSTATUS(status) == 0)
{
int v;
if(read(pipes[i][0], &v, sizeof v)==sizeof(v)){
randomNumSum+=v;
}
} else
fprintf(stderr, "Cannot read from child %d with pid: %d\n", i, pids[i]);
// close pipe even if read fails
// or child exited abnormally
close(pipes[i][0]);
}
//保存子项的所有PID!
pid_t pid[numProcess];
for(int i=0;iNote to users with closing rights:请不要投票关闭此问题的副本。OP有一个新问题,我建议OP不要更改原始问题的代码(因为我的答案可能不再有意义)然后写一个新问题。再看一下我在旧问题答案中的第一个代码。您使用的是管道技术,但您不是在分叉之前使用管道(pipes[i])
创建管道。