如何使用管道通信两个进程

Posted

技术标签:

【中文标题】如何使用管道通信两个进程【英文标题】:How to communicate two processes using pipes 【发布时间】:2015-09-02 10:46:11 【问题描述】:

我正在使用命名管道在两个进程之间进行通信。

作家.c

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

int main()

    int fd;
    char * myfifo = "/tmp/myfifo";

    /* create the FIFO (named pipe) */
    mkfifo(myfifo, 0666);

    /* write "Hi" to the FIFO */
    fd = open(myfifo, O_WRONLY);
    write(fd, "hi", sizeof("hi"));
    write(fd, "4:1.jpg,2.jpg;3.jpg", sizeof("4:1.jpg,2.jpg;3.jpg"));
    write(fd, "hi2", sizeof("hi2"));
    write(fd, "5:1.jpg,2.jpg;3.jpg", sizeof("5:1.jpg,2.jpg;3.jpg"));
    write(fd, "6:1.jpg,2.jpg;3.jpg", sizeof("6:1.jpg,2.jpg;3.jpg"));
    write(fd, "7:1.jpg,2.jpg;3.jpg", sizeof("6:1.jpg,2.jpg;3.jpg"));
    write(fd, "8:1.jpg,2.jpg;3.jpg", sizeof("6:1.jpg,2.jpg;3.jpg"));
    write(fd, "9:1.jpg,2.jpg;3.jpg", sizeof("6:1.jpg,2.jpg;3.jpg"));
    sleep(5);
return 0;


阅读器.c

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

#define MAX_BUF 2048

int main()

    int fd;
    char * myfifo = "/tmp/myfifo";
    char buf[MAX_BUF];
    /* open, read, and display the message from the FIFO */
    fd = open(myfifo, O_RDONLY);
      int i;
      for( i =0; i < 6 ; i++)
      
      int a = read(fd, buf, MAX_BUF);
       printf("buf has : %s with size = %d \n", buf,a);
       

    return 0;

输出如下:

buf has : hi with size = 3
buf has : 4:1.jpg,2.jpg;3.jpg with size = 124
buf has : 4:1.jpg,2.jpg;3.jpg with size = 0
buf has : 4:1.jpg,2.jpg;3.jpg with size = 0
buf has : 4:1.jpg,2.jpg;3.jpg with size = 0
buf has : 4:1.jpg,2.jpg;3.jpg with size = 0

我想知道其他字符串去了哪里?有人可以告诉我出了什么问题。我需要输出就像所有字符串必须一个接一个地出现。

【问题讨论】:

【参考方案1】:

read 调用返回了您已写入 fifo 的所有数据。您的字符串有 20 个字节长(19 个字节的文本和一个终止符 \0)。加上 4 个字节的“hi2”。第二次读取返回大小 124 (6*20+4)。

Fifos 包含数据流,而不是单独的消息。每次成功写入都不会成功读取一次。您可以获得比写入更少或更多的读取,并且由您来发明一种协议,该协议允许您分离消息并在阅读器中缓冲以收集和重组消息,如果它们分布在多个读取中。

您的 printf 只打印“第一条”消息(没有消息,只有字节流)的原因是因为它是零终止的。所以其他字符串在您的缓冲区中,但是由于您将整个缓冲区作为字符串打印,因此只会显示其中的第一个字符串。

【讨论】:

【参考方案2】:

您必须等待传入数据 - 当a == 0 时,管道中仍然没有数据。在int a = ... 之后添加:

if ( a == 0 )

  i--; // repeat last iteration
  continue;

最好先发送行数,然后您就会知道将到达多少文本行。

【讨论】:

以上是关于如何使用管道通信两个进程的主要内容,如果未能解决你的问题,请参考以下文章

进程通信方式-管道pipe

实验8 进程间通信

实验八进程间通信

多进程通信之管道运用

简述Linux进程间通信之命名管道FIFO

c - 使用管道在两个子进程之间持续通信