【发布时间】:2011-08-26 03:45:10
【问题描述】:
对于一些涉及信号量的请求,我们的 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);
这个sn-p在一个并发访问非常频繁的区域。事实上,这被放置在我们内部开发的 StreamWrapper 实现中,以支持我们自己的操作。似乎并发是相关的,因为我们按顺序进行了测试并且没有发现任何问题。
关于可能是什么原因的任何见解?另外,我不确定 sem_remove() 在做什么,因为我没有找到对应的系统调用。
附:我们删除了所有包含 sem_*() 的语句,似乎我们不再遇到此问题。
【问题讨论】:
-
你能更清楚地定义“随机 PHP 请求失败”吗?
-
好的。由于未知原因,PHP 请求的处理突然终止。这种情况并非每次都发生。如前所述,它偶尔会在相同的参数集下发生,这就是我所说的“随机”。执行路径包括许多未显示的特定于应用程序的处理。但是,当它需要访问某种文件存储设施时,它会通过包含引用的 sn-p 的 StreamWrapper 实现。