微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用命名pipe道在fopen上设置超时

我正在尝试使用命名pipe道在PHP中执行一些IPC。 我有一个通过创build命名pipe道

$pipePath = __DIR__ . '/pipe'; posix_mkfifo($pipePath,0600);

完成一些计算后,还有另外一个应该写入该pipe道的进程。 我可以等待它完成,并阅读类似这样的结果:

$result = file_get_contents($pipePath);

或者更详细

$in = fopen($pipePath,'r'); $result = fread($in,8192); fclose($in);

(我已经简化了第二种方法;在实际的代码中,我会检查错误,在循环中运行fread以防结果大于8192字节等)

fopen()无法打开stream:权限被拒绝,但权限应该是有效的

如何select开放模式与fopen()?

C ++ CreateFile和fopen函数抢先读取整个远程文件

由于权限,无法在Windows 7中使用fopen进行读取或写入

打开窗户

然而,当另一个进程完成时,我不相信它是成功的,所以我想暂时尝试读取结果。 在等待一段时间后,我想放弃并报告一个错误,说它崩溃了,等等。用这两种方法PHP代码将永远挂起(或很长一段时间)等待一些东西写入pipe道。 具体来说, file_get_contents和fread将挂起。

我能够想出的唯一解决scheme就是这样的:

$timeout = 10; //seconds for ($i = 0; $i < $timeout; $i++) { $in = @fopen($pipePath,'rn'); if ($in) break; sleep(1); } if (!$in) { throw new RuntimeException("The other process did not finish in the allotted time"); } $result = fread($in,8192); fclose($in);

这使用未logging的'n'标志fopen ,如在这个问题上的一个评论中所示。 它会导致fopen呼叫立即失败,如果它会阻止。

但是,我不喜欢这个解决scheme有两个原因:

通过每秒检查pipe道来做不必要的工作。

如果在另一个进程中的计算需要1.01秒完成,这将等待整整2秒钟来获得结果。 对于我想要做的一些事情来说,这已经足够浪费时间了,值得尝试解决这个问题。

当在一个URL上调用fopen ,我可以添加一个context参数指定一个超时值。 但是,这似乎并没有为此工作,也没有设置套接字超时。

有没有更好的方法来做到这一点与pipe道? 如果不是的话,我可能会考虑切换到Unix套接字,但是在其他进程中不太容易支持,所以我宁愿不这样做。

(仅供参考,我只关心Linux;无需在Windows或其他任何东西上运行,以防万一)。

文件描述符消失/无效

Linux中无缓冲的I / O

fopen不返回

fopen / fdopen冻结破碎的networking共享或移除USB设备

多个进程可以使用fopen附加到文件而没有任何并发​​问题?

我找到了一个方法来做到这一点…

首先,我不知道n标志,这是非常有用的信息!

但是,如果功能被阻塞,功能也不完全正确。 它仍然返回一个文件句柄。 我们可以使用文件句柄并将其传递给stream_select函数,以等待数据可用。

像这样的东西:

$f=fopen("my.fifo","rn"); $r=array($f); $w=array(); $x=array(); stream_select($r,$w,$x,10);

这段代码等待10秒钟让其他人写入FIFO的另一端。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐