【问题标题】:Communication between pipes in linuxlinux中管道之间的通信
【发布时间】:2014-03-28 13:54:35
【问题描述】:

我有两个函数 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 没有被正确创建。我不知道如何解决这个问题。需要更多帮助。

感谢您的帮助。

【问题讨论】:

  • 在调用写入器/读取器之前,在 main 方法中创建 fifo。
  • 尝试在 main() 中创建 fifo,给出输出:消息写道:这是一条消息消息是:
  • 成功了,抱歉,在 main() 中创建 fifo 后,我没有在读写器函数中更改 fifo 的名称,现在改了,效果很好。谢谢你的帮助

标签: c++ linux pipe


【解决方案1】:

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

mkfifo("/tmp/pipe", 0666) 之类的东西,在您在阅读器/编写器中打开 /tmp/pipe 之前。

还可以看看fifo man page

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

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

要试一试,让阅读器运行,然后使用echo "test" &gt; /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 &lt;thread&gt;,添加此编译器标志:-std=c++0x,并将以下库添加到链接器:-lpthread

【讨论】:

  • 我做了fifo,但现在终端上没有输出。这就是我创建 fifo 'int res = mkfifo("/tmp/mypipe", 0666);' 的方式
【解决方案2】:

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

包括errno.h:

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

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

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

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

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-24
      • 2010-12-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多