pthread_cond_timedwait
是pthread
库中用于等待条件变量的函数之一,它和pthread_cond_wait
类似,都是用于等待某个条件变量。然而,pthread_cond_timedwait
允许线程等待一定的时间,如果在指定时间内没有收到信号,它会超时返回,从而避免线程无限期地阻塞。
pthread_cond_wait 示例
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define BUFFER_SIZE 10
int buffer[BUFFER_SIZE];
int count = 0; // 当前缓冲区中的项目数
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_producer = PTHREAD_COND_INITIALIZER;
pthread_cond_t cond_consumer = PTHREAD_COND_INITIALIZER;
void* producer(void* arg) {
while (1) {
pthread_mutex_lock(&mutex);
// 如果缓冲区满,等待消费者消费
while (count == BUFFER_SIZE) {
pthread_cond_wait(&cond_producer, &mutex);
}
// 生产一个项目
buffer[count++] = rand() % 100;
printf("Produced item %d\n", buffer[count-1]);
// 通知消费者可以消费
pthread_cond_signal(&cond_consumer);
pthread_mutex_unlock(&mutex);
}
return NULL;
}
void* consumer(void* arg) {
while (1) {
pthread_mutex_lock(&mutex);
// 如果缓冲区为空,等待生产者生产
while (count == 0) {
pthread_cond_wait(&cond_consumer, &mutex);
}
// 消费一个项目
printf("Consumed item %d\n", buffer[--count]);
// 通知生产者可以生产
pthread_cond_signal(&cond_producer);
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main() {
pthread_t prod_thread, cons_thread;
pthread_create(&prod_thread, NULL, producer, NULL);
pthread_create(&cons_thread, NULL, consumer, NULL);
pthread_join(prod_thread, NULL);
pthread_join(cons_thread, NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond_producer);
pthread_cond_destroy(&cond_consumer);
return 0;
}
pthread_cond_timedwait 示例
pthread_cond_timedwait
可用于需要等待特定条件但又不希望无限期等待的场景。通过设定超时时间,线程可以等待一段时间后执行其他操作,避免因为未收到条件变量的信号而陷入长时间的阻塞。
函数定义
int pthread_cond_timedwait(pthread_cond_t *cond,
pthread_mutex_t *mutex,
const struct timespec *abstime);
-
参数:
cond
:条件变量指针。mutex
:互斥量指针。与pthread_cond_wait
一样,pthread_cond_timedwait
需要先锁定互斥量。abstime
:指定的超时时间,类型为struct timespec
,表示绝对时间(即从某个时间点开始到目标时间的总时间,而不是相对时间)。
-
返回值:
0
:成功被唤醒。ETIMEDOUT
:超时,未被唤醒。- 其他错误码:失败。
关键点:
pthread_cond_timedwait
使用绝对时间来指定超时时间,通常使用clock_gettime
获取当前时间,然后将所需的超时时间加到timespec
的tv_sec
或tv_nsec
字段中。- 使用
pthread_cond_timedwait
的线程需要锁定互斥量,它会自动解锁互斥量,直到超时或收到信号时重新加锁。 - 超时返回
ETIMEDOUT
,可以用来区分是正常被唤醒还是超时。
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <errno.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int shared_data = 0;
void* producer(void* arg) {
sleep(2); // 模拟生产过程
pthread_mutex_lock(&mutex);
shared_data = 1; // 生产数据
printf("Producer: Data produced\n");
pthread_cond_signal(&cond); // 唤醒等待的消费者
pthread_mutex_unlock(&mutex);
return NULL;
}
void* consumer(void* arg) {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts); // 获取当前时间
ts.tv_sec += 5; // 设置 5 秒的超时时间
pthread_mutex_lock(&mutex);
while (shared_data == 0) {
int res = pthread_cond_timedwait(&cond, &mutex, &ts);
if (res == ETIMEDOUT) {
printf("Consumer: Wait timed out\n");
break;
} else {
printf("Consumer: Data consumed\n");
}
}
pthread_mutex_unlock(&mutex);
return NULL;
}
int main() {
pthread_t prod_thread, cons_thread;
pthread_create(&prod_thread, NULL, producer, NULL);
pthread_create(&cons_thread, NULL, consumer, NULL);
pthread_join(prod_thread, NULL);
pthread_join(cons_thread, NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}