我正在尝试使用命名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] 举报,一经查实,本站将立刻删除。