命名管道卡在打开状态

Posted

技术标签:

【中文标题】命名管道卡在打开状态【英文标题】:Named PIPE is stuck on open 【发布时间】:2017-07-06 07:37:55 【问题描述】:

我正在尝试实现一个named PIPE IPC 方法,每次调用sendToPipe 函数时,我都会发送float 值(10)。这是sendToPipe 函数-

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

void sendToPipe(paTestData *data)

    int readCount   = 10;
    fd      = open(fifoPipe, O_WRONLY);   // Getting stuck here

    // Reading 10 sample float values from a buffer from readFromCB pointer as the initial address on each call to sendToPipe function.
    while(readCount > 0)

        write(fd, &data->sampleValues[data->readFromCB], sizeof(SAMPLE));  // SAMPLE is of float datatype
        data->readFromCB++;
        readCount--;
    

    close(fd);

    //  Some code here

我已经在我的main 中初始化了named PIPE

int main()

    // Some code
    mkfifo(fifoPipe, S_IWUSR | S_IRUSR);

    // Other code

我不知道我在哪里出错了。任何帮助表示赞赏。如果需要任何其他信息,也请告诉我。

【问题讨论】:

首先你必须检查mkfifo返回值... 检查errno 看看发生了什么:if (result < 0) perror ("mkfifo"); exit (2); 。然后看看the man C++ Linux named pipe hanging on open() with O_WRONLY的可能重复 好的,所以错误是:FILE_EXIST。我删除了管道并再次执行 mkfifo 的 0 退出值。 要解锁这种情况,您可以轻松地与阅读器启动另一个线程。之后,我开始考虑在发送方准备整个缓冲区,包含 10 个值,并将它们一次性写入管道。因此读取器将被唤醒(在阻塞模式下),它可以在一次读取中读取所有值。 【参考方案1】:

总结所有评论点:

    程序正在“冻结”,因为管道的另一端没有读卡器。 第一个程序启动后,管道已创建。下一个程序启动将返回 FILE_EXIST 错误。 要一次将 10 个值写入管道,使读取器能够一次接收所有值,您应该准备一个缓冲区,然后打开管道并写入它(阻塞模式)。作为旁注,请注意阅读器方面:读取功能不会一次性检索整个缓冲区,因此您必须检查返回的读取数据编号。

【讨论】:

在读取过程中如何从命名的 PIPE 中检索完整数据? read 返回读取了多少字节,所以循环读取直到达到正确的数量。 如果我需要进程来创建管道然后从中读取,它会永远卡住,即使在我运行另一个尝试在那里写入的进程之后也是如此。两者都会卡住。【参考方案2】:

感谢@LPs 指出出了什么问题。进入 PIPE 后,我的每个样本都在等待阅读。然而,我想要一个实现,其中我的阅读器线程可以一次读取所有 10 个样本。这是我的实现。 -

void pipeData(paTestData *data)

    SAMPLE *tempBuff = (SAMPLE*)malloc(sizeof(SAMPLE)*FRAME_SIZE);
    int readCount   = FRAME_SIZE;

    while(readCount > 0)

        tempBuff[FRAME_SIZE - readCount] = data->sampleValues[data->readFromCB];        
        data->readFromCB++;
        readCount--;
    

    fd = open(fifoPipe, O_WRONLY);

    write(fd, tempBuff, sizeof(tempBuff));
    // Reader thread called here

    close(fd);

【讨论】:

以上是关于命名管道卡在打开状态的主要内容,如果未能解决你的问题,请参考以下文章

如何等待 n 秒以打开命名管道?

非阻塞命名管道

在断开连接之前等待读取命名管道

为啥只读打开命名管道块?

打开命名管道时,构造函数上的 FileInputStream 块

Linux:打开命名管道进行写入时超时