Aus*_*tin 6 php linux fopen ipc
我正在尝试使用命名管道在PHP中进行一些IPC.我有一个名为pipe的管道
$pipePath = __DIR__ . '/pipe';
posix_mkfifo($pipePath, 0600);
Run Code Online (Sandbox Code Playgroud)
在完成一些计算之后,还有另一个进程应写入该管道.我可以等待它完成并用以下内容读取结果:
$result = file_get_contents($pipePath);
Run Code Online (Sandbox Code Playgroud)
或者更冗长
$in = fopen($pipePath, 'r');
$result = fread($in, 8192);
fclose($in);
Run Code Online (Sandbox Code Playgroud)
(我简化了第二种方法;在实际代码中,我会检查错误,fread在循环中运行,以防结果> 8192字节,等等)
但是,虽然其他进程应该完成,但我不相信它会成功,所以我想尝试读取结果时超时.在等待一段时间之后,我想放弃并报告错误,说它崩溃等等.给出两种方法,PHP代码将永远挂起(或者很长一段时间)等待写入管道的东西.具体来说,file_get_contents和fread将挂起.
我能想出的唯一解决方案是这样的:
$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);
Run Code Online (Sandbox Code Playgroud)
这使用未记录的'n'标志,如此问题fopen的评论之一所示.如果它会阻塞,它会导致调用立即失败.fopen
但是,我不喜欢这个解决方案有两个原因:
当fopen在URL上调用时,我能够添加指定超时值的上下文参数.但是,这似乎不适用于此,也没有设置默认套接字超时.
用管道有更好的方法吗?如果没有,我可能会考虑切换到Unix套接字,但在其他过程中这些并不那么容易支持,所以我宁愿不这样做.
(仅供参考,我只关心Linux;如果这很重要,不需要在Windows或其他任何东西上运行.)
我找到了一种方法来做到这一点......
首先,我不知道国旗n,这是非常有用的信息!
然而,如果函数阻塞的话,函数就会失败,这并不完全正确。它仍然返回一个文件句柄。我们可以使用文件句柄并将其传递给函数stream_select以等待数据可用。
像这样的东西:
$f=fopen("my.fifo","rn");
$r=array($f);
$w=array();
$x=array();
stream_select($r,$w,$x,10);
Run Code Online (Sandbox Code Playgroud)
此代码等待 10 秒,以便其他人写入 fifo 的另一端。
| 归档时间: |
|
| 查看次数: |
807 次 |
| 最近记录: |