我在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 1293php源代码显示了获取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看到我在下面发布的说明。
拉杰
发布于 2008-11-07 16:27:17
我不会忽略ENOSPC (正如代码所示,除了EINTR之外,您还得到了其他东西)。您可能会在繁忙的循环中等待先前耗尽的资源。如果你在某个地方没有空间,你想确保你能处理好这个问题。ENOSPC通常意味着您退出了of...something。
一些随机的想法:
我不是PHP实现方面的专家,但每次需要信号量时,我都会尽量避免调用sem_get()。把手柄储存起来。可能是因为对sem_get的每次调用都与某些资源相关联,而这正是您耗尽空间的地方。
我会确保在sem_get()上检查您的错误返回。这是一个代码片段,但如果无法获得sema4,则在尝试sem_op()时会得到不一致的结果(也许EINTR是有意义的)
发布于 2008-11-07 17:31:39
在发布了这个问题之后,我注意到我将代码误读为errno errno EINTR,并得出结论。因此,正如bog所指出的,错误是ENOSPC而不是EINTR。经过一番挖掘,我找到了ENOSPC的原因。撤消缓冲区的数量正在耗尽。我增加了semmnu的数量,现在代码正在运行,没有问题。我使用semmni*semmsl作为semmnu的值。
https://stackoverflow.com/questions/272504
复制相似问题