如果子进程在阅读时不会从写入中关闭管道会发生什么?

给出以下代码:

int main(int argc,char *argv[])
{
    int pipefd[2];
    pid_t cpid;
    char buf;

    if (argc != 2) {
        fprintf(stderr,"Usage: %s \n",argv[0]);
        exit(EXIT_FAILURE);
    }

    if (pipe(pipefd) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    cpid = fork();
    if (cpid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (cpid == 0) {    /* Child reads from pipe */
        close(pipefd[1]);          /* Close unused write end */

        while (read(pipefd[0],&buf,1) > 0)
            write(STDOUT_FILENO,1);

        write(STDOUT_FILENO,"\n",1);
        close(pipefd[0]);
        _exit(EXIT_SUCCESS);

    } else {            /* Parent writes argv[1] to pipe */
        close(pipefd[0]);          /* Close unused read end */
        write(pipefd[1],argv[1],strlen(argv[1]));
        close(pipefd[1]);          /* Reader will see EOF */
        wait(NULL);                /* Wait for child */
        exit(EXIT_SUCCESS);
    }
return 0;

}

每当子进程想要从管道读取时,它必须首先关闭管道侧写入.当我删除该行关闭(pipefd [1]);从子进程的if,
我基本上说“好吧,孩子可以从管道读取,但我允许父母同时写入管道”?

如果是这样的话,当管道打开以进行读取时会发生什么?写作?没有相互排斥?

最佳答案

Whenever the child process wants to read from the pipe,it must first close the pipe’s side from writing.

如果进程 – 父进程或子进程 – 不打算使用管道的写端,则应该关闭该文件描述符.类似地,对于管道的读取端.系统将假定在任何进程打开写入结束时可能发生写入,即使唯一的此类进程是当前尝试从管道读取的进程,因此系统也不会报告EOF.此外,如果您溢出管道并且仍然存在读取结束打开的进程(即使该进程是尝试写入的进程),则写入将挂起,等待读取器为写入完成留出空间.

When I remove that line close(pipefd[1]); from the child’s process IF,I’m basically saying that “okay,the child can read from the pipe,but I’m allowing the parent to write to the pipe at the same time”?

没有;你说孩子可以写信给管道和父母.具有管道的写文件描述符的任何进程都可以写入管道.

If so,what would happen when the pipe is open for both reading and writing — no mutual exclusion?

从来没有任何相互排斥.管道写入描述符打开的任何进程都可以随时写入管道;内核确保两个并发写操作实际上是序列化的.打开管道读取描述符的任何进程都可以随时从管道读取;内核确保两个并发读操作获得不同的数据字节.

通过确保只有一个进程打开以进行写入并且只有一个进程打开以进行读取,确保单向使用管道.但是,这是一个编程决定.你可以有N个进程,写入结束打开,M进程读取结束打开(并且,思想消失,N组和M组进程之间可能存在共同的进程),并且它们都能够出乎意料地工作.但是你不可能很容易地预测在写入数据包之后将在何处读取数据包.

相关文章

linux常用进程通信方式包括管道(pipe)、有名管道(FIFO)、...
Linux性能观测工具按类别可分为系统级别和进程级别,系统级别...
本文详细介绍了curl命令基础和高级用法,包括跳过https的证书...
本文包含作者工作中常用到的一些命令,用于诊断网络、磁盘占满...
linux的平均负载表示运行态和就绪态及不可中断状态(正在io)的...
CPU上下文频繁切换会导致系统性能下降,切换分为进程切换、线...