【问题标题】:Using multiple pipes in c在c中使用多个管道
【发布时间】:2019-05-04 16:19:50
【问题描述】:

我不想编写一个使用 2 个管道在父进程和子进程之间传递值的程序。代码:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/stat.h>
#include <fcntl.h>

int mkfifo(const char *path, mode_t mode);

int main(int argc, char **argv)
{
  int fd,df,val;
  char * myfifo = "/tmp/myfifo";
  mkfifo(myfifo, 0666);

  char * myfifo2 = "/tmp/myfifo2";
  mkfifo(myfifo2, 0666);

  pid_t c=fork();

  if(c==0){
    df = open(myfifo2, O_RDONLY);
    read(df, &val, sizeof(val));
    close(df);
    val= val+10;
    df = open(myfifo2, O_WRONLY);
    write(df, &val, sizeof(val));
    fd = open(myfifo, O_WRONLY); //if i put this write first print works and program finishes
    write(fd, &val, sizeof(val));

      }
  if(c>0)
   {
    val=1;
    df = open(myfifo2, O_WRONLY); 
    write(df, &val, sizeof(val)); 
    fd = open(myfifo, O_RDONLY);
    read(fd, &val, sizeof(val));
    printf("val is %d \n",val);

        }
}

子进程的第一次读取等待父进程在fifo文件中写入val。之后它将一个新的val写入这个fifo文件,然后将一个值写入第二个文本文件。读取父进程的代码等待这个写要发生。所以,总而言之,我想要的是父进程仅在子进程在 myfifo2 文件中写入 val 后才执行打印。这就是我使用的第二个命名管道的目的。但是,这段代码得到了卡住并且什么也不打印。我注意到,如果我改变两个在子进程中写入的轮次,它可以工作,但它不能满足我需要的上述内容。为什么会发生这种情况,我该如何解决这个问题?

【问题讨论】:

  • 你为什么要使用命名管道呢?使用pipe 创建管道。

标签: c operating-system


【解决方案1】:

发生了什么

虽然命名管道可以与缓冲一起使用(如您所愿),但依靠它不会阻塞您的程序(因为这就是您所拥有的,死锁 ) 是一种非常糟糕的做法。

此外,它带有一些警告:

  • 为了有那种“缓冲”的效果,需要打开管道的两端(man 7 fifo

    FIFO 必须在两端(读取和写入)都打开,才能传递数据。通常,打开FIFO会阻塞,直到另一端也打开。

  • 一旦管道达到其容量,写入最终将阻塞。此大小取决于系统,但可以通过F_SETPIPE_SZ fcntl 设置。而且:

    请注意,由于管道缓冲区页面的方式 数据写入管道时使用的字节数 可以写入的可能小于标称大小,具体取决于- 了解写入的大小。

所以,你有这种情况:

  • 父母(可能,甚至可能还不在那里)在read 上等待/tmp/myfifo

  • /tmp/myfifo2 被父级打开WR_ONLY

  • 子调用df = open(myfifo2, O_WRONLY);,打开/tmp/myfifo2 WR_ONLY。因此管道的读取端打开,因此对open 的调用会阻塞。

  • 死锁

要解决这个问题,在孩子中以读写方式打开myfifo2应该就足够了。

df = open(myfifo2, O_RDWR); // instead of df = open(myfifo2, O_WRONLY);

不过,IMO 这种通信模式看起来有点奇怪(而且难以理解)。

【讨论】:

  • 谢谢您的详细回答。确实使用0_RDWR 有效。只是一个小问题。为什么在孩子执行写行之前,孩子的读取没有读取父亲写入的值?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-03
  • 2019-09-12
相关资源
最近更新 更多