![我如何知道写入命名管道是否会阻塞?](https://linux22.com/image/140224/%E6%88%91%E5%A6%82%E4%BD%95%E7%9F%A5%E9%81%93%E5%86%99%E5%85%A5%E5%91%BD%E5%90%8D%E7%AE%A1%E9%81%93%E6%98%AF%E5%90%A6%E4%BC%9A%E9%98%BB%E5%A1%9E%EF%BC%9F.png)
仅当命名管道已有读取器时,我才想写入该管道。目前,我正在用来timeout
检测写入管道的尝试是否被阻止,如下所示:
#! /usr/bin/env bash
rm -f pipe
mkfifo pipe
sleep 5
timeout 1 bash -c "echo Hello > pipe"
if [[ $? == 0 ]]
then
echo Somebody got our message
else
echo Nobody read from pipe, so we didn\'t send a message
fi
这有效。如果我tail -f pipe
在睡眠期间使用单独的终端,我会收到一条消息,如果没有,我会收到另一条消息。但还有更好的办法吗?理想情况下,它应该是不依赖超时的东西。
答案1
如果你想写入管道,只有当有某个进程打开它进行读取时,你才可以以非阻塞模式打开它进行写入。
使用 GNU dd
:
echo Hello | dd oflag=nonblock of=pipe status=none &&
echo message has been sent
您将收到 ENXIO 的错误消息(类似于没有这样的设备或地址英文)如果没有读者。
请注意,它也会失败(使用EWOULDBLOCK
/ EAGAIN
,资源暂时不可用)如果管道已满(如果有读取器,但当前未读取并且已写入 64KiB 之类的内容)。
另请注意,如果不适合,则无法写入所有消息。如果删除status=none
,您将看到写入了多少内容。