命名管道创建

Posted

技术标签:

【中文标题】命名管道创建【英文标题】:Named pipe creation 【发布时间】:2011-06-06 02:21:26 【问题描述】:

我正在尝试使用命名管道。我有一个读取信息的进程和另一个将信息写入管道的进程。

这是我的阅读器进程的简化代码:

main (int argc, char *argv[]) 
  int fd, mkn;
  char message[100];

  if(unlink("aPipe") == -1) 
      perror("Error unlinking:");
  


  if((mkn = mknod("aPipe", S_IFIFO, 0)) < 0)
    perror("Error mknod:");
  

  if(chmod("aPipe", 0660)) 
    perror("Error chmod:");
   

  if(fd = open("aPipe", O_RDONLY) < 0) 
    perror("Error abriendo el PIPE");
   

    printf("going to read..\n");

close(fd);

但它永远停留在这一行:if(fd = open("aPipe", O_RDONLY) &lt; 0),我真的不明白为什么。

如果你知道哪个手册页说这里发生了什么,请告诉我:)

【问题讨论】:

哪个进程负责创建 FIFO:读取器或写入器(或者应该在任何一个启动之前创建)?如果您的阅读器删除了编写器创建的 FIFO,它将在打开时阻塞,因为它的新管道上没有编写器;相反,如果写入器删除了读取器创建的 FIFO,它将在打开时阻塞,因为没有读取器。此外,您应该使用mkfifo() 而不是mknod()(尽管在大约二十年前,您会使用mknod(),因为mkfifo() 不存在)。 【参考方案1】:

FIFO 有点奇怪; open() 作为作家将阻塞,直到有读者,反之亦然。更糟糕的是,就像真正的管道一样,当写入器关闭其末端时,读取端将永远返回 EOF;您必须关闭并重新打开(阻止下一个读者)。或者你 open(fifo, O_RDWR) 然后你需要一些方法来知道编写器何时完成,例如让它只使用一行或有一个带内 EOF 数据包。

【讨论】:

【参考方案2】:

代码如下:

读者:

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

readline(int fd, char *str) 
int n;
do 
    n = read(fd, str, 1);
    if(n == -1)
        perror("Error reading:");
    

while(n > 0 && (str++) != NULL);

return(n > 0);

main (int argc, char *argv[]) 
int fd, mkn;
char message[100];

if(unlink("aPipe") == -1) 
    perror("Error unlinking:");


if((mkn = mknod("aPipe", S_IFIFO, 0)) < 0)
    perror("Error mknod:");


if(chmod("aPipe", 0660)) 
    perror("Error chmod:");


if(fd = open("aPipe", O_RDONLY) < 0) 
    perror("Error abriendo el PIPE");

printf("going to read..\n");
while(readline(fd,message))
    printf("%s\n", message);
close(fd);

作者:

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

main (int argc, char *argv[]) 
int fd, messagelen,i;
char message[100];

sprintf(message, "Hello from PID %d", getpid());

messagelen = strlen(message) + 1;
do 
    fd = open("aPipe", O_WRONLY|O_NDELAY);
    if (fd == -1) 
        perror("opening aPipe:");
        sleep(1);
    

while(fd == -1);

for (i = 1; i < 4; i++) 
    if(write(fd, message, messagelen) == -1) 
        perror("Error writing:");
    
    sleep(3);

close(fd);
 

我也得学makefifo,但是在我明白了这个之后。

非常感谢您的宝贵帮助!

【讨论】:

如果你想添加一些东西,你应该编辑你的问题而不是添加答案,除非你自己找到了解决方案并且你实际上是在回答你自己的问题。【参考方案3】:

是否有任何进程写入 FIFO? 如果不是,这是预期的行为,因为您在阻塞模式下打开了 FIFO RDONLY,当前进程将不会继续,直到有进程实际写入 FIFO。

【讨论】:

是的,我有这个打开管道的过程:fd = open("aPipe", O_WRONLY|O_NDELAY);对 open 的调用是一个 do while(fd == -1);,但无论如何,它总是显示错误:没有这样的设备或地址 一方必须将 O_CREAT 传递给 open() 才能创建管道。 不 mknod 创建管道? 我会使用mkfifo()系统调用来创建一个FIFO。而且,如果您能向我们展示您的协作编写过程的代码,那将会很有帮助。

以上是关于命名管道创建的主要内容,如果未能解决你的问题,请参考以下文章

Windows 8 命名管道创建

命名管道创建

命名管道类似于“mkfifo”创建,但双向

c++下使用命名管道实现进程间通信

Linux进程间通信

Linux进程间通信