【问题标题】:EINTR error for semop callsemop 调用的 EINTR 错误
【发布时间】:2008-11-07 15:48:25
【问题描述】:

我在 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 吗?

编辑:我误解了这个问题,请参阅我在下面发布的说明。

拉吉

【问题讨论】:

    标签: php c semaphore


    【解决方案1】:

    我不会忽略 ENOSPC(如代码所示,您得到的不是 EINTR)。您可能最终会进入一个繁忙的循环,等待您之前用尽的资源。如果您在某处没有空间,则要确保处理该问题。 ENOSPC 通常意味着你没有……某事。

    一些随机的想法:

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

    我会确保在sem_get() 上检查您的错误返回。这是一个代码sn-p,但是如果你没有得到sema4,你在尝试sem_op()它时会得到不一致的结果(也许EINTR有意义)

    【讨论】:

      【解决方案2】:

      发布此问题后,我注意到我将代码误读为errno == EINTR 并得出结论。所以正如博格所指出的,错误是ENOSPC 而不是EINTR。经过一番挖掘,我找到了ENOSPC 的原因。撤消缓冲区的数量已用尽。我增加了semmnu 的数量,现在代码运行没有问题。我使用semmni*semmsl 作为semmnu的值

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-11-02
        • 2015-05-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-01
        • 1970-01-01
        • 2020-12-09
        相关资源
        最近更新 更多