如何写入命名管道而不等待读取管道
Posted
技术标签:
【中文标题】如何写入命名管道而不等待读取管道【英文标题】:how to write to a named pipe and don't wait for reading the pipe 【发布时间】:2012-09-04 13:33:09 【问题描述】:我正在写入管道,直到用户输入字符串“end”。如果用户输入字符串“end”,我想更进一步。在这里,我必须关闭管道并打印消息“写入管道后”。但是即使我输入了“结束”字符串,它也没有打印“写入管道后”行。即使没有读取管道的过程,我如何关闭管道并走得更远?..
您好,这是我的代码。,
int main()
int fd;
char *b, *c;
printf("Enter Str : ");
b = malloc(50);
gets(b);
while(strcmp(b,"end")!=0)
if(access("MSG",F_OK) != -1) // check pipe is already available.
fd = open("MSG", O_WRONLY);
write(fd, b, strlen(b) );
else
if( mkfifo("MSG", 0666) != -1) // create pipe if not available.
fd = open("MSG", O_WRONLY);
write(fd, b, strlen(b) );
printf("Enter Str : ");
gets(b);
close(fd);
printf("After Written to Pipe");
【问题讨论】:
那里有一大块(不必要的)代码重复。您可以使用if (access("MSG", F_OK) != 0) if (mkfifo("MSG", 0666) != 0) ... report error and stop...
,然后拥有一份open()
和write()
。您应该考虑如果 FIFO 创建失败会发生什么。您应该考虑如果open()
失败会发生什么。您可能会考虑检查来自write()
的返回值。除非您成功打开 fd
,否则不应调用 close()
(但关闭应该在打开的循环中;您正在泄漏文件描述符)。您确定要在循环中打开 FIFO 吗?
【参考方案1】:
来自mkfifo(3)
手册页:
但是,它必须同时在两端打开,然后才能继续对其进行任何输入或输出操作。打开一个 FIFO 进行读取通常会阻塞,直到其他进程打开同一个 FIFO 进行写入,反之亦然。
上述段落表示write
将阻塞,直到有人从 FIFO 中读取,这就是您在程序中看到的。
【讨论】:
【参考方案2】:命名管道在这里不是合适的工具,因为bash
无法在非阻塞模式下使用它们。
您可以使用类似于cat
的编程语言编写工具,但不会阻塞。但是none of the results I found 让我很高兴向您推荐它们。
否则它是套接字(使用netcat
和localhost
),不幸的是,它是不安全的,因为您计算机上的所有其他用户也可以访问它们......
或某种充当缓冲区的普通文件。但是您会遇到如何删除已阅读的行以使其不会泛滥的问题,以及竞争条件以及所有那些噩梦。
很抱歉,这里确实没有好的解决方案。要以正确的方式解决此问题,需要修补 bash 和 cat 以添加允许非阻塞行为的选项。
【讨论】:
以上是关于如何写入命名管道而不等待读取管道的主要内容,如果未能解决你的问题,请参考以下文章