linux中管道之间的通信

时间:2014-03-28 13:54:36

标签: c++ linux pipe

我有两个功能 writer() reader()。我正在写一个来自writer()函数的消息并从reader()函数中读取它。我面临的问题是消息正在管道中写入,但它没有被读取。打开管道可能有问题需要阅读。代码是:

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

using namespace std;

//edit
int fifo = mkfifo("/tmp/mypipe", S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH);

void writer()
{
    char message[] = "this is a message";
    int fd;
    fd = open("pipe" , O_WRONLY);
    write(fd , message , sizeof(message));
    cout<<"message wrote: "<<message<<"\n";     // gives output 
}                                               // message wrote: this is a message

void reader()
{
    char buffer[100];
    int fd;
    fd = open("pipe" , O_RDONLY);
    read(fd , buffer , 100);
    cout<<"message is: "<<buffer<<"\n";     // gives output
}                                           // message is:

int main()
{
    writer();
    reader();
    return 0;
}

我调试了它,我认为问题是,fifo没有正确创建。我不知道如何解决这个问题。需要更多帮助。

enter image description here

感谢您的帮助。

3 个答案:

答案 0 :(得分:3)

我的猜测是你没有以正确的方式创建管道。看看mkfifo man page。对于umask值,请查看umask man page

在您在读者/作者中打开mkfifo("/tmp/pipe", 0666)之前,

类似于/tmp/pipe

另请查看fifo man page

  

内核为每个FIFO特殊维护一个管道对象    由至少一个进程打开的文件。必须打开FIFO    在数据传递之前的两端(读和写)。    通常,打开FIFO块直到另一端打开。

所以你现在的问题是,open(..., O_WRONLY)阻止读者打开文件。

要试用它,只需让读者运行,然后使用echo "test" > /tmp/pipe

<强>更新

或者使用线程,我只是试了一下。

int main() {
    mkfifo(fifo_name.c_str(), 0666);
    std::thread w(writer);     
    std::thread r(reader); 
    w.join();
    r.join();
    unlink(fifo_name.c_str());
    return 0;
}

您还必须#include <thread>,添加此编译器标志:-std=c++0x并将以下库添加到链接器:-lpthread

答案 1 :(得分:2)

请务必检查函数调用的返回值,因为它们可以告诉您问题所在。

包括errno.h:

#include <errno.h>
#include <string.h>

当您从写入或读取打开尝试返回错误时检查错误:

fd = open("pipe" , O_WRONLY);
if (fd < 0)
{   
    cout << "writer open failed: " << errno << "(" << strerror(errno) << ")\n";
    /* exit */
}   

正如另一个答案所述,你没有使用mkfifo(),所以你要制作一个典型的文件(如果你不提供O_CREAT和模式参数,它也会有效但可能会失败)。

答案 2 :(得分:1)

它是关于命名管道在posix中如何工作的。如果已经有某人正在阅读它,你只能写入它。如果没有,则write()操作将被阻止,直到有人不读。

最简单的解决方案是,如果

  1. 您使用了非阻塞I / O
  2. 您在不同的进程(线程)中实现了读者和编写者,并在编写者之前调用了读者。