PHP命名管道,php – 如何使用命名管道在fopen上设置超时

在PHP中使用命名管道进行进程间通信时,遇到读取操作可能无限期阻塞的问题。作者讨论了如何设置超时来避免这种情况,提出了一个通过循环和sleep函数实现的简易超时机制。然而,这种方法存在效率低下和可能延迟过长的缺点。文章询问是否存在更好的管道读取超时解决方案,或者是否应转向使用Unix套接字作为替代方案。
摘要由CSDN通过智能技术生成

我正在尝试使用命名管道在

PHP中进行一些IPC.我有一个名为pipe的管道

$pipePath = __DIR__ . '/pipe';

posix_mkfifo($pipePath, 0600);

在完成一些计算之后,还有另一个进程应写入该管道.我可以等待它完成并用以下内容读取结果:

$result = file_get_contents($pipePath);

或者更冗长

$in = fopen($pipePath, 'r');

$result = fread($in, 8192);

fclose($in);

(我简化了第二种方法;在实际代码中我会检查错误,在循环中运行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);

这使用未记录的’n’标志来进行fopen,如this question中的一个注释所示.如果fopen调用阻塞,则会导致fopen调用立即失败.

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

>通过每秒检查一次管道,它做了不必要的工作.

>如果另一个过程中的计算需要1.01秒才能完成,这将等待整整2秒钟以获得结果.对于我想做的一些事情,这是浪费的时间,值得尝试解决问题.

当在URL上调用fopen时,我可以添加指定超时值的上下文参数.但是,这似乎不适用于此,也没有设置默认套接字超时.

用管道有更好的方法吗?如果没有,我可能会考虑切换到Unix套接字,但在其他过程中这些并不那么容易支持,所以我宁愿不这样做.

(仅供参考,我只关心Linux;如果这很重要,不需要在Windows或其他任何东西上运行.)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值