我有一个生产脚本,可以将文件从一个已安装的网络共享复制并重命名到另一个文件(两个CIFS),有时copy
函数在读取I / O时无限期挂起,从而使该进程进入不间断的睡眠状态,在该状态下它只能被SIGKILL.
杀死(非常感谢,显然是TASK_KILLABLE。)
由于在copy
调用中操作被阻塞,所以我无法优雅地处理I / O故障,更重要的是,不能记录它。
$res = copy("/path/to/mount/file.pdf", "/path/to/productionqueue/newfile.pdf");
//This doesn't run because of the process state.
if($res) {
//Report success to the log.
} else {
//Report failure to the log.
}
这是一个环境,特定于文件的问题,可以通过人工干预来解决,但我需要记录故障,以便可以将这种情况通知管理员。 (此外:我认为这是一个锁定竞争条件。我可以通过卸载和重新安装源共享来解决此问题,但是重现它是一个问题。)
理想情况下,我希望copy
调用在10秒后超时,因此我可以记录该错误,但是PHP中似乎没有办法做到这一点。
我正在考虑将复制或读取操作委派给timeout
命令监视的子进程,并根据退出代码进行响应,但是PHP脚本中有没有更简单的方法来处理这种情况? ?
我在搜索中发现的所有内容都表明只有套接字/网络超时可用的运行时配置,而不是文件系统调用。
答案 0 :(得分:0)
据我所知,答案没有-没有内置的方法可以使PHP中的文件读取操作超时。但是,在I / O为TASK_KILLABLE
的系统上,您可以在子进程中执行I / O操作,并使用timeout -s 9
终止它。然后timeout
将返回非零的退出状态。
例如,使用cp
实用程序:
$ssrc = escapeshellarg($src);
$sdst = escapeshellarg($dst);
//10 second timeout, send KILL
exec("timeout -s 9 10 cp $ssrc $sdst 2>&1", $output, $ret);
if($ret != 0) {
log("Failed copying $src to $dst, exit status: $ret");
}