我在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\u 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?
编辑:我误解了这个问题,请看下面的澄清。
拉吉

最佳答案

我不会忽略ENOSPC(代码显示,您得到的不是EINTR)。你可能会在一个繁忙的循环中等待一个你之前耗尽的资源。如果你在某个地方没有空间,你要确保你能处理好这个问题。ENOSPC通常意味着你失去了…一些东西。
一些随机的想法:
我不是PHP实现方面的专家,但每次需要信号量时,我都会尽量避免调用sem_get()。把手柄放好。可能是每个对sem_get的调用都关联了一些资源,这就是空间不足的地方。
我会确保在sem_get()上检查您的错误返回。这是一个代码片段,但是如果您未能获得sema4,那么在尝试sem_op()时会得到不一致的结果(也许EINTR是有意义的)

关于php - semop调用的EINTR错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/272504/

10-11 21:02