命名管道创建
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) < 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。而且,如果您能向我们展示您的协作编写过程的代码,那将会很有帮助。以上是关于命名管道创建的主要内容,如果未能解决你的问题,请参考以下文章