如何使用管道传递两个进程

时间:2015-09-02 10:46:12

标签: c ipc named-pipes

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

Writer.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;

}

Reader.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

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

2 个答案:

答案 0 :(得分:1)

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

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

你的printf只打印&#34;第一个&#34;消息(没有消息,只有字节流)是因为它是零终止的。所以其他字符串在你的缓冲区中,但是因为你将整个缓冲区作为字符串打印,所以只显示其中的第一个字符串。

答案 1 :(得分:0)

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

if ( a == 0 )
{
  i--; // repeat last iteration
  continue;
}

最好首先发送行数,然后你就会知道会有多少行文字到达。