linux – 如何确定是否可以写入管道

linux – 如何确定是否可以写入管道,第1张

概述有没有办法(在C中,或最好在Perl中)确定是否可以写入命名管道 – 即有一个有效的读取过程 似乎如果我打开写入非阻塞,open会立即返回,但select for write也会立即返回. 目标是如果读取结束尚未准备好,则写入过程仅进行(即跳过发送) 有可能你没有注意打开的返回码.如果打开FIFO进行写入和非阻塞,则有两种可能的结果. >如果已有读卡器,则打开将立即成功返回. >如果没有管道读取器 有没有办法(在C中,或最好在Perl中)确定是否可以写入命名管道 – 即有一个有效的读取过程
似乎如果我打开写入非阻塞,open会立即返回,但select for write也会立即返回.
目标是如果读取结束尚未准备好,则写入过程仅进行(即跳过发送)解决方法 有可能你没有注意打开的返回码.如果打开FIFO进行写入和非阻塞,则有两种可能的结果.

>如果已有读卡器,则打开将立即成功返回.
>如果没有管道读取器,则打开将失败并显示errno = ENXIO.

以下程序演示.

#include<stdio.h>#include<unistd.h>#include<errno.h>#include<fcntl.h>#include<stdlib.h>#include <sys/stat.h>#define SERVFIFO "/tmp/server.fifo"#define file_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)voID syserr(const char *str){    perror(str);    exit(1);}int main(int argc,char** argv){    umask(0);    if (mkfifo(SERVFIFO,file_MODE) < 0 && errno != EEXIST)        syserr("mkfifo");    // try to open for write with no readers    int fDW = open(SERVFIFO,O_WRONLY | O_NONBLOCK);    if (fDW == -1)        perror("non-blocking open for write with no readers Failed");    // create a reader - the process itself - non-blocking    int fdr = open(SERVFIFO,O_RDONLY | O_NONBLOCK);    if (fdr == -1)        syserr("non-blocking open for read no writers Failed");    // try again to open for write but this time with a reader    fDW = open(SERVFIFO,O_WRONLY | O_NONBLOCK);    if (fDW == -1)        syserr("non-blocking open with readers Failed");    printf("non-blocking open for write succeeded\n");    close(fDW);    close(fdr);    unlink(SERVFIFO);}

也就是说,open没有阻塞就失败的事实并不是那么有用.关于你唯一能做的就是不断尝试打开,直到你成功,这种轮询可能是浪费,而在长期运行程序的情况下等待间歇性读者是有点荒谬的.

一种解决方案是上面使用的 – 打开FIFO以便自己阅读 – 但这有其自身的问题.

>如果在select语句中使用FIFO写入fd,它总是可写的……直到它不可写.也就是说,因为您也是自己的读取器,所以FIFO写入将成功,直到您使用PIPE_BUF字节填充FIFO缓冲区.之后,FIFO将无法写入,并且您的写入将在EAGAIN中失败,直到合法读取器(即非您自己)出现,打开以进行读取,并开始耗尽缓冲区.
>通过打开自己的FIFO进行读写,当合法用户关闭FIFO时,您将看不到EOF.由于您只关心写作,这对您来说可能不是问题.

我从未尝试过的另一种可能的解决方案是在FIFO上使用inotify.您可以在选择中监视inotify文件描述符,并确定何时有人打开FIFO.然后你知道你可以安全地开始写作.您可能希望屏蔽FIFO上的打开权限,以便您可以成为唯一的编写者,如果可能的话,您的应用程序.

对于这些时髦的语义,FIFO应该被重命名为PITA.如果你能做出改变,这就是为什么Unix众神赋予我们凡人的域名套接字.

总结

以上是内存溢出为你收集整理的linux – 如何确定是否可以写入管道全部内容,希望文章能够帮你解决linux – 如何确定是否可以写入管道所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/yw/1033168.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存