semop 调用的 EINTR 错误
我在 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 吗?
编辑:我误解了这个问题,请参阅我在下面发布的澄清。
拉吉
I am using the following code fragment in a php script to safely update a shared resource.
$lock_id = sem_get( ftok( 'tmp/this.lock', 'r'));
sem_acquire($lock_id)
//do something
sem_release($lock_id)
When I stress test this code with large number of requests I get an error:
Warning: semop() failed acquiring SYSVSEM_SETVAL for key 0x1e: No space left on device in blahblah.php on line 1293
php sources show the following code for failed acquiring 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;
}
}
which means semop fails with EINTR. man page reveals that the semop() system call was interrupted by a signal.
My question is can I safely ignore this error and retry sem_acquire?
Edit: I have misunderstood this problem, Pl see the clarification I have posted below.
raj
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不会忽略 ENOSPC(正如代码所示,您会得到除 EINTR 之外的其他内容)。 您可能会陷入一个繁忙的循环中,等待先前耗尽的资源。 如果您在某个地方没有空间,您需要确保解决该问题。 ENOSPC 通常意味着您没有……某事。
一些随机的想法:
我不是 PHP 实现方面的专家,但我会尽量避免每次需要信号量时都调用 sem_get() 。 而是存放手柄。 可能某些资源与每次调用 sem_get 相关联,这就是您空间不足的地方。
我会确保检查您在
sem_get()
上返回的错误。 这是一个代码片段,但如果您无法获取 sema4,则在尝试使用 sem_op() 时会得到不一致的结果(也许 EINTR 有意义)I wouldn't ignore the ENOSPC (you're getting something other than EINTR, as the code shows). You may end up in a busy loop waiting for a resource that you have earlier exhausted. If you're out of some space somewhere, you want to make sure that you deal with that issue. ENOSPC generally means you are out of...something.
A couple of random ideas:
I am not an expert on the PHP implementation, but I'd try to avoid calling
sem_get()
each time you want the semaphore. Store the handle instead. It may be that some resource is associated with each call to sem_get, and that is where you're running out of space.I'd make sure to check your error returns on
sem_get()
. It's a code snippet, but if you were to fail to get the sema4, you would get inconsistent results when trying tosem_op()
it (perhaps EINTR makes sense)发布这个问题后,我注意到我将代码误读为
errno
==
EINTR
并得出结论。 正如 bog 所指出的,错误是ENOSPC
而不是EINTR
。 经过一番挖掘,我找到了ENOSPC
的原因。 撤消缓冲区的数量即将耗尽。 我增加了semmnu
的数量,现在代码运行没有问题。 我使用semmni*semms
l 作为semmnu
的值After posting this question I noticed that I misread the code as
errno
==
EINTR
and jumped into conclusion. So as bog has pointed out, the error isENOSPC
and notEINTR
. After some digging I located the reason forENOSPC
. The number of undo buffers were getting exhausted. I have increased the number ofsemmnu
and now the code is running with out issues. I have usedsemmni*semms
l as the value ofsemmnu