我们的Web服务器已经看到一些涉及信号量的请求的随机PHP请求失败。我们跟踪并怀疑由于PHP中的sem _ *()函数而导致请求死亡,但我们无法从错误日志中挖掘任何有用的东西。我们在64位Linux机器上使用PHP 5.3.6。代码运行如下:
$sem_id = @sem_get(123457, 1);
if (!$sem_id) return;
$sem_retval = @sem_acquire($sem_id);
if (!$sem_retval) return;
$shm_id = shmop_open(ftok('/some/path', 'h'), 'c', 0666, 8192);
if ($shm_id === FALSE) { @sem_release($sem_id); return; }
$str = shmop_read($shm_id, 0, 8192);
// ... some operations that may result in changes to $data
if ($data_updated) {
shmop_write($shm_id, str_pad(serialize($data), 8192, "\0"), 0);
}
@shmop_close($shm_id);
@sem_release($sem_id);
@sem_remove($sem_id);
此代码段位于具有并发访问频率的区域中。事实上,这是我们内部开发的StreamWrapper实现,用于支持我们自己的操作。看起来并发性是相关的,因为我们按顺序测试并没有发现任何问题。
有关可能原因的任何见解?另外,我不确定sem_remove()正在做什么,因为我找不到系统调用对应物。
P.S。我们删除了包含sem _ *()的所有语句,似乎我们不再遇到问题。
答案 0 :(得分:0)
您需要立即使用@ -operator停止。这会掩盖任何错误,并使其无声地被忽略,即使它会导致致命的退出。
@运算符是PHP最糟糕的功能之一。
如果发生错误,因为您正在使用@运算符,您无法知道它是什么,甚至根本不知道它发生了,因为您的脚本无论如何都会无处可寻,或者退出时没有有尊严的数据。即使您已设置错误日志记录并将error_reporting设置为其最大值,这也适用。