semop调用的EINTR错误

时间:2008-11-07 15:48:25

标签: php c semaphore

我在php脚本中使用以下代码片段来安全地更新共享资源。

$lock_id = sem_get( ftok( 'tmp/this.lock', 'r'));
sem_acquire($lock_id)
//do something
sem_release($lock_id)

当我用大量请求对此代码进行压力测试时,我收到错误:

Warning: semop() failed acquiring SYSVSEM_SETVAL for key 0x1e: No space left on device in blahblah.php on line 1293

php源代码显示以下代码未能获取SYSVSEM_SETVAL

while (semop(semid, sop, 3) == -1) {
    if (errno != EINTR) {
        php3_error(E_WARNING, "semop() failed acquiring SYSVSEM_SETVAL for key 0x%x: %s", key, strerror(errno));
        break;
    }
}

表示semop因EINTR而失败。手册页显示semop()系统调用被信号中断。

我的问题是我可以安全地忽略此错误并重试sem_acquire吗?

编辑:我误解了这个问题,Pl看到我在下面发布的说明。

拉​​吉

2 个答案:

答案 0 :(得分:1)

我不会忽略ENOSPC(你得到的不是EINTR,如代码所示)。您可能会在忙碌的循环中等待您之前用尽的资源。如果你在某个地方没有某个空间,你想确保你处理这个问题。 ENOSPC通常意味着你不在......某事。

一些随意的想法:

我不是PHP实现的专家,但我会尽量避免在每次需要信号量时调用sem_get()。改为存放手柄。可能是某些资源与每次调用sem_get相关联,而这正是您的空间不足的地方。

我一定要检查sem_get()上的错误回复。这是一个代码片段,但是如果你没有得到sema4,那么在尝试sem_op()时会得到不一致的结果(也许是EINTR有意义)

答案 1 :(得分:0)

发布此问题后,我发现我误解了代码为errno == EINTR,并跳了起来。正如bog指出的那样,错误是ENOSPC而不是EINTR。经过一番挖掘后,我找到了ENOSPC的原因。撤消缓冲区的数量已经耗尽。我增加了semmnu的数量,现在代码正在运行,没有问题。我使用semmni*semms l作为semmnu

的值