如果等待时间为 0 [重复],则定义sem_timedwait

Is sem_timedwait defined if the time to wait is 0 [duplicate]

提问人:0___________ 提问时间:10/29/2023 最后编辑:0___________ 更新时间:10/29/2023 访问量:68

问:

如果等待时间为 0,则定义,或者我应该在这种情况下调用?文档不清楚,源代码仅显示实现。sem_timedwaitsem_trywait

我想知道 Posix 标准是否说明了时间尚未到期且未到期的情况。

编辑

决定不要偷懒:

        switch(xTicksToWait)
        {
            case SEMAPHORE_MAXWAIT:
                result = sem_wait(sem);
                break;
            case SEMAPHORE_NOWAIT:
                result = sem_trywait(sem);
                break;
            default:
                ts.tv_sec += xTicksToWait / 1000;
                ts.tv_nsec += (xTicksToWait % 1000) * 1000000ULL;
                ts.tv_sec += ts.tv_nsec / 1000000000ULL;
                ts.tv_nsec = ts.tv_nsec % 1000000000ULL;
                result = sem_timedwait(sem, &ts);
                break;
        }
C Linux pthreads 信号量

评论

3赞 Weather Vane 10/29/2023
“打开组”页面没有说现在是等待时间,而是说绝对时间:当 abstime 指定的绝对时间过去时,超时将过期,该时间由超时所依据的时钟测量(即,当该时钟的值等于或超过 abstime 时),或者如果 abstime 指定的绝对时间在调用时已经过去。即使指定了时间间隔,似乎也不清楚。
0赞 0___________ 10/29/2023
@WeatherVane我知道文档,我知道这是绝对的时间。我认为很容易理解我的意思。案例:未过期,将来不会。否则有什么意义(除了保存键盘?sem_trywait
3赞 Weather Vane 10/29/2023
时间已经过了:文件非常清楚:等于或超过
0赞 John Bollinger 11/1/2023
当我们可以满足所有相同的目的甚至更多时,有什么意义呢?有时,由于各种原因,API 是多余的。printf()fprintf()

答:

2赞 Oka 10/29/2023 #1

从sem_timedwait(3)中:

sem_timedwait()与 相同,不同之处在于abs_timeout指定了在无法立即执行递减时调用应阻止的时间限制。该参数指向一个结构,该结构指定自 1970-01-01 00:00:00 +0000 (UTC) 纪元以来的绝对超时(以秒和纳秒为单位)。sem_wait()abs_timeout

零秒的绝对超时将是 Epoch。

这将始终立即导致以下结果之一:

如果调用时超时已过期,并且无法立即锁定信号量,则 sem_timedwait() 将失败并出现超时错误(errno 设置为 ETIMEDOUT)。

如果可以立即执行该操作,则无论 abs_timeout 的值如何,sem_timedwait() 都不会失败并出现超时错误。此外,在这种情况下,不会检查abs_timeout的有效性。

手册页上的示例显示了从相对时间间隔创建绝对超时(使用 clock_gettime(2))。删减的片段:

int s;
struct timespec ts;

/* Calculate relative interval as current time plus
       number of seconds given argv[2] */

if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
    handle_error("clock_gettime");

ts.tv_sec += atoi(argv[2]);

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");

需要注意的无效参数是:

EINVAL
的值小于 0,或大于等于 10 亿。
abs_timeout.tv_nsecs

评论

0赞 0___________ 10/29/2023
谢谢 - 但它没有回答我的问题。我知道文档,从那里发布示例根本没有意义。我希望从知道它的人那里得到答案。
3赞 Shawn 10/29/2023
@0____引用的文档非常清楚地说明了过去的时间会发生什么。未过期,将来也不会过期你能描述一个这样的例子吗?
0赞 0___________ 10/29/2023
如果很清楚,我不会问这个问题