导致失败的PHP信号量


PHP Semaphores causing failures?

我们的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()在做什么,因为我没有发现对应的系统调用。

注:我们删除了所有包含sem_*()的语句,似乎再也不会遇到这个问题了。

您需要立即停止使用@-操作符。这将掩盖任何错误,并使其被静默忽略,即使它导致致命的退出。

@操作符是PHP最糟糕的特性之一。

如果因为使用@操作符而发生错误,则无法知道它是什么,甚至根本无法知道它发生了什么,因为脚本要么继续运行,要么在没有诊断数据的情况下退出。即使您设置了错误日志记录并将error_reporting设置为最大值,这也适用。