pthread_cond_timedwait 函数

pthread_cond_timedwait 函数

1
2
3
4
5
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);
int pthread_cond_wait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex);

pthread_cond_timedwait 用于等待一个条件变量,等待条件变量的同时可以设置等待超时。其中 abstime 超时时间是一个绝对值,也就是距离 1970-1-1 的时间值,而不是一个时间段。比如说当前时间为:2023-05-28 17:06:00.100,我想要通过这个函数设置最大超时为 3000ms,那么就需要设置 abstime 的时间为:2023-05-28 17:06:03.100

同时,建议大家使用单调时间,而非系统时间。因为系统时间可能存在跳变的问题。

如下举个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <pthread.h>
#include <time.h>
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <errno.h>

static int64_t tm_to_ns(struct timespec ts) {
return ts.tv_sec * 1E9 + ts.tv_nsec;
}

static struct timespec ns_to_tm(int64_t ns) {
struct timespec ts;
ts.tv_sec = ns / 1E9;
ts.tv_nsec = ns - (ts.tv_sec * 1E9);
return ts;
}

int main() {
pthread_mutex_t mtx;
pthread_mutex_init(&mtx, nullptr);

pthread_cond_t cond;
pthread_condattr_t attr;
pthread_condattr_init(&attr);
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
pthread_cond_init(&cond, &attr);
pthread_condattr_destroy(&attr);

struct timespec start_tm;
struct timespec end_tm;
int timeout_ms = 3000;
clock_gettime(CLOCK_MONOTONIC, &start_tm);
end_tm = ns_to_tm(tm_to_ns(start_tm) + timeout_ms * 1E6);

pthread_mutex_lock(&mtx);
for (;;) {
if (pthread_cond_timedwait(&cond, &mtx, &end_tm) == ETIMEDOUT) {
printf("Timed out\n");
break;
}
}
pthread_mutex_unlock(&mtx);
return 0;
}