使用管道与从stdin读取的多个子进程进行通信

时间:2018-09-27 09:32:34

标签: c unix pipe fork

我正在努力正确地理解fork()pipe()execvp(),并希望获得有关此代码在哪里出错以及应该从何而来的指南。据我了解,如果要运行多个进程,请使用fork()语句for n次,如下所示。要维护对父代与众多子代之间的每个通信“通道”的引用,请使用2D文件描述符(例如fd[n][2])。此外,要允许2种方式通信,您需要使用2个FD。调用exevp()时,它将用execvp()创建的过程替换被调用的过程。

因此,我创建了一个简单的程序,该程序分叉一个进程的2个副本,其唯一目的是立即返回父进程发送的字符串。从这一刻开始,它应该向子进程0,然后是子进程1发送一条消息。然后,它永恒地等待,直到完成某些操作以终止子进程或父进程为止。但是,我遇到2个问题。首先,此当前程序在父进程的第一个read / printf语句处停止,我得到以下结果,提示我输入按Enter时不执行任何操作的值。我知道发生此错误是由于我的execvp程序造成的,因为删除了fgets并只是printf输入了一个值并退出了预期的工作。但是,我需要在那里fgets,因为我希望能够返回到该过程并稍后发送更多消息。

Child 0
|         <--- Prompts me to enter value

预期:

Child 0
Process 0 received: test message
Child 1
Process 1 received: test message

这是我的主程序:

int main () {
    char buff[50];
    int pipe_parent[2][2];
    int pipe_child[2][2];
    int pids[2];
    for (int i = 0; i < 2; i++) {
        char id[snprintf(NULL, 0, "%d", i) + 1];
        sprintf(id, "%d", i);
        char* prog[] = {"./test", id, NULL};

        if (pipe(pipe_parent[i]) == -1 || pipe(pipe_child[i]) == -1) {
            exit(1);
        }

        int pid = fork();
        if (pid > 0) {
            pids[i] = pid;
            close(pipe_child[i][0]);
            close(pipe_parent[i][1]);
            int in = pipe_child[i][1];
            int out = pipe_parent[i][0];
            write(out, "test message\n", 13); //hard coded but should use strlen + 1
            read(in, buff, 50);
            //The code below does not work and so probably the read above too
            printf("Child: %s", buff); //Does not print anything and starts waiting for use input here.
            //Inputting anything here does nothing
        } else if (pid == 0) { 
            print("Child %d", i);
            close(pipe_child[i][1]);
            close(pipe_parent[i][0]);
            dup2(pipe_child[i][0], STDIN_FILENO);
            dup2(pipe_parent[i][1], STDOUT_FILENO);
            close(pipe_child[i][0]);
            close(pipe_child[i][1]);
            execvp(prog[0], prog);
            exit(1); //Should not reach here unless error
        } //Should add error check here with else

    for (int i = 0; i < 2; i++) {
        int status;
        waitpid(pids[i], &status, 0);
    }

    return 0;
}

和我的另一个获得execvp的程序:

int main(int argc, char** argv) {
    char buff[50];
    while(fgets(buff, sizeof(buff), stdin) != NULL) {
        printf("Process &d received: %s", atoi(argv[1]), buff);
    }
    printf("Process %d closed", atoi(argv[1]));
    return 0;
}

我的第二个问题是,假设以上程序正常工作,我不知道如何选择与特定过程进行通信。我希望程序以某种方式发送消息,以向进程0,然后1,然后0,...等发送消息(依我指定的其他顺序),直到完成阻止它的操作为止。我认为对于简单的0,1,0,1 ...代码,代码看起来像这样:

int counter = 0;
while(counter < 5) {
    for (int i = 0; i < 2; i++) {
        //setup out and in to be pipe_child/parent[i][0/1]
        write(out, "message", len);
        //read();
        //printf();
    }
    counter++;
}

如果我可以在哪里找到可以工作的提示,将不胜感激。

编辑:execl()execvp()

0 个答案:

没有答案