管道卡在读(C - 系统调用)

时间:2018-06-16 09:47:22

标签: c pipe system-calls

这是我第一次使用C,所以到目前为止一直很困难。 我的程序读取file.txt。 在第一行中,我必须创建子项的数量(var:NPROC),在剩下的行中我必须读取子进程的id,两个整数和一个我必须计算的操作的字符: 例如:

.env

我必须使用消息队列(完美地运行)将操作(逐行)发送给孩子,然后孩子应该使用管道发回结果。

这是代码:

(父亲)

NPROC
(id) (n1) (op) (n2)
2
2 3 + 1
1 5 / 2
2 9 * 3

现在我的问题是父亲的阅读似乎没有得到消息。 当我执行程序时,不要退出,它会在父亲的读取中循环(保持不变)。 我试图将读取放在for(因此它至少应该读取最后一条消息),但程序仍然停留在读取中。 如果有人能帮助我,我将非常感激。

1 个答案:

答案 0 :(得分:1)

您的代码充满了问题。

switch(currentPid = fork()){
    case 0:

在这里你需要关闭管道的读取端:

        close(p[0]);

通常在此dup2之前您有一个execl。通常,如果您的子进程要加载另一个程序,您希望将其stdout重定向到管道的写入端,如dup2(p[1], 1); close(p[1]);中所示。

        execl("./child", "./child", NULL);

        return 0;
    case -1:
        printf("Error when forking\n");
        break;
    default:

        // in the father
        childrenPids[i] = currentPid; // store current child pid
        wait(NULL);

wait来电是错误的。如果孩子输出的数据多于管道可以同时容纳的数据,那么这里就会出现死锁(孩子将在write中阻塞,等待父母read管道的一些数据,然后才能退出;父母将在wait中阻止,等待孩子退出,然后再从管道中读出来。)

在你给它做任何事情之前等待孩子退出是没有意义的。这不应该是一种类似协处理器的设计,即孩子们应该继续沿着父母运行,根据请求做算术并将结果发回去吗?

        printf("\nParentpid:  %d, Childpid: %i \n", getpid(), currentPid);

        //close(p[1]);

为什么close被注释掉了?父进程关闭管道的写入端是至关重要的(因为否则从管道的读取端读取将阻塞,因为写入端仍在某处打开(在同一过程中,在这种情况下)。)

        if(read(p[0], &val, sizeof(val) == -1){

这行甚至没有编译。缺少)

            perror("read()\n");
            exit(1);
        }

你错过了一张EOF支票。 read在到达数据末尾时将返回0(并且val未初始化)。

您应该使用管道中的所有可用数据(直到read返回0),然后才会使用waitpid(currentPid, NULL, 0);

相关问题