我正在阅读sem_timedwait()上的手册,无法理解这个示例。我目前的理解是:
sem_timedwait()超时,则返回-1并将errno设置为ETIMEDOUT。因此,我可以检查它是否超时,而不是被发出信号。sem_timedwait()由sem_post()发出信号,它将返回0所以我理解if-语句,但是我不理解while循环。因此,当sem_timedwait()返回一个错误(?)时,它会循环。当它被一个sem_post()呼叫发出信号的时候?(我显然不明白"EINTR The call was interrupted by a signal handler"的定义)
人类的例子:
while ((s = sem_timedwait(&sem, &ts)) == -1 && errno == EINTR)
continue; /* Restart if interrupted by handler */
/* Check what happened */
if (s == -1) {
if (errno == ETIMEDOUT)
printf("sem_timedwait() timed out\n");
else
perror("sem_timedwait");
} else
printf("sem_timedwait() succeeded\n");我认为它的工作原理与此类似:
s = sem_timedwait(&sem, &ts)
if (errno == ETIMEDOUT) {
// timed out after specified ts
}
else if (s == -1) {
// error occurred
}
else {
// interrupted by `sem_post()`, do something relying on shared resource
}发布于 2018-09-14 12:16:09
while循环:
while ((s = sem_timedwait(&sem, &ts)) == -1 && errno == EINTR)
continue; /* Restart if interrupted by handler */循环,直到sem_timedwait调用成功(即。( sem_post()发生了),或者发生了EINTR以外的错误。
EINTR错误是专门处理的,因为sem_timedwait调用可以在任何时候被信号中断。这不是一个错误,而是一个中断(这就是它),在这种情况下,调用只是重试。
发布于 2018-09-14 12:27:04
任何进程都可以接收信号。如果该进程正在执行系统调用,当接收到信号时阻止该进程,系统调用将失败,全局耶诺将被设置为特殊值EINTR。这样,流程就会再次被唤醒,并在接收到信号时采取行动。
这并不是一个很难的失败,它主要是信息,一个信号已经收到,人们可以安全地再次进行同样的呼叫。
这里的代码只是遵循良好的实践和处理这种潜在的情况。由于这里的代码并不真正关心信号是否被接收,所以它只是重新尝试获取信号量。
注意,虽然大多数系统调用可能以这种方式失败,但大多数系统调用都会自动重新启动。也就是说,您自己的代码从未看到调用在EINTR中失败,系统重新尝试系统调用。在调用sigaction()时,还可以通过安装信号处理程序来控制此行为。
然而,sem-timedwait()并不是系统自动重新启动的调用,因此您的代码必须处理它。
https://stackoverflow.com/questions/52331735
复制相似问题