C for Linux中的进程和无限循环

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>

以下是我试图做的:

编写一个接受整数命令行参数n的C程序, 生成n个进程,每个进程将在 -然后计算并打印出这些随机数的总和。每个进程都需要打印出随机数 产生

这就是我到目前为止所做的:

#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])
创建管道。