理解 sem_timedwait()

Understanding sem_timedwait()

我正在阅读 sem_timedwait() 上的手册,但无法理解示例。我目前的理解是:

所以我理解 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()但是,不是系统自动重启的调用,所以你的代码必须处理它。