linux 管道怎么读写,linux – 如何确定是否可以写入管道

有可能你没有注意打开的返回码.如果打开FIFO进行写入和非阻塞,则有两种可能的结果.

>如果已有读卡器,则打开将立即成功返回.

>如果没有管道读取器,则打开将失败并显示errno = ENXIO.

以下程序演示.

#include

#include

#include

#include

#include

#include

#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众神赋予我们凡人的域名套接字.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值