理解 sem_timedwait()
Understanding sem_timedwait()
我正在阅读 sem_timedwait()
上的手册,但无法理解示例。我目前的理解是:
- 如果
sem_timedwait()
超时,则 returns -1 并将 errno
设置为 ETIMEDOUT
。因此,我可以检查它是否超时而不是被通知。
sem_timedwait()
如果由 sem_post()
发出信号,则 return 0
所以我理解 if 语句,但是我不理解 while 循环。所以它会在 sem_timedwait()
return 出现错误(?)并且它被 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
}
while
循环:
while ((s = sem_timedwait(&sem, &ts)) == -1 && errno == EINTR)
continue; /* Restart if interrupted by handler */
将循环直到 sem_timedwait
调用成功(即发生 sem_post()
),或者发生 EINTR
以外的错误。
error is handled specially, because the sem_timedwait
调用可以随时被信号中断。这不被视为错误,而是被视为中断(是),并且在这种情况下会重试调用。
任何可以接收 signals . If that process is doing a system call that blocks the process when the signal is received, the system call will fail, and the global errno 的进程都将被设置为特殊值 EINTR
。这样进程就会再次被唤醒,并可以在收到信号时采取行动。
这不是硬故障,主要是收到信号并且可以安全地再次进行相同调用的信息。
此处的代码只是遵循良好做法并处理这种潜在情况。由于此处的代码并不关心是否收到信号,它只是重新尝试获取信号量。
请注意,虽然大多数系统调用可能会以这种方式失败,但大多数系统调用会自动重新启动。也就是说,您自己的代码永远不会看到调用因 EINTR 而失败,系统会再次重试系统调用。当通过调用 sigaction()
安装信号处理程序时,也可以控制此行为。
sem-timedwait()
但是,不是系统自动重启的调用,所以你的代码必须处理它。
我正在阅读 sem_timedwait()
上的手册,但无法理解示例。我目前的理解是:
- 如果
sem_timedwait()
超时,则 returns -1 并将errno
设置为ETIMEDOUT
。因此,我可以检查它是否超时而不是被通知。 sem_timedwait()
如果由sem_post()
发出信号,则 return 0
所以我理解 if 语句,但是我不理解 while 循环。所以它会在 sem_timedwait()
return 出现错误(?)并且它被 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
}
while
循环:
while ((s = sem_timedwait(&sem, &ts)) == -1 && errno == EINTR)
continue; /* Restart if interrupted by handler */
将循环直到 sem_timedwait
调用成功(即发生 sem_post()
),或者发生 EINTR
以外的错误。
sem_timedwait
调用可以随时被信号中断。这不被视为错误,而是被视为中断(是),并且在这种情况下会重试调用。
任何可以接收 signals . If that process is doing a system call that blocks the process when the signal is received, the system call will fail, and the global errno 的进程都将被设置为特殊值 EINTR
。这样进程就会再次被唤醒,并可以在收到信号时采取行动。
这不是硬故障,主要是收到信号并且可以安全地再次进行相同调用的信息。
此处的代码只是遵循良好做法并处理这种潜在情况。由于此处的代码并不关心是否收到信号,它只是重新尝试获取信号量。
请注意,虽然大多数系统调用可能会以这种方式失败,但大多数系统调用会自动重新启动。也就是说,您自己的代码永远不会看到调用因 EINTR 而失败,系统会再次重试系统调用。当通过调用 sigaction()
安装信号处理程序时,也可以控制此行为。
sem-timedwait()
但是,不是系统自动重启的调用,所以你的代码必须处理它。