本文共 1810 字,大约阅读时间需要 6 分钟。
条件变量是一种在多线程环境中用于同步的机制,通过共享全局变量实现线程间的一致性操作。其主要功能是允许一个线程等待某个条件满足而暂停(条件等待),另一个线程则可以给予条件满足信号(激发条件)。为了防止竞争条件的产生,条件变量的使用通常与互斥锁结合使用。
条件变量的创建和销毁与互斥锁类似,提供了静态和动态两种方式:
静态创建:通过PTHREAD_COND_INITIALIZER常量初始化条件变量。例如:
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
动态创建:调用pthread_cond_init()函数,API定义如下:
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);
在LinuxThreads实现中,cond_attr通常为NULL且被忽略。条件变量没有属性资源,因此注销时只需检查是否有线程正在等待该条件。
注销条件变量:调用pthread_cond_destroy(),API如下:
int pthread_cond_destroy(pthread_cond_t *cond);
注销成功的条件是没有线程正在等待该条件,否则返回EBUSY。
条件变量的等待和激发操作如下:
无条件等待:pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
计时等待:pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
pthread_cond_wait和pthread_cond_timedwait都需要与一个互斥锁配合使用,以防止竞争条件。互斥锁必须是PTHREAD_MUTEX_TIMED_NP或PTHREAD_MUTEX_ADAPTIVE_NP类型,且在调用等待函数前必须由本线程加锁。互斥锁在条件满足时会被重新加锁,以确保线程进入等待前的加锁动作得到对应。
pthread_cond_signal(pthread_cond_t *cond)激活一个等待该条件的线程,pthread_cond_broadcast(pthread_cond_t *cond)激活所有等待该条件的线程。考虑以下场景:两个线程A和B分别执行decrement_count和increment_count函数,管理一个计数器count。假设线程A首先执行decrement_count:
#include#include static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;unsigned count = 0;void decrement_count() { pthread_mutex_lock(&mtx); while (count == 0) { pthread_cond_wait(&cond, &mtx); } count--; pthread_mutex_unlock(&mtx);}
线程B执行increment_count:
void increment_count() { pthread_mutex_lock(&mtx); if (count == 0) { pthread_cond_signal(&cond); } count++; pthread_mutex_unlock(&mtx);} 在这种设计中:
pthread_cond_wait被阻塞至count不为零。count为零时激活条件,唤醒线程A。count并解锁。count并解锁。这种设计确保了计数器的正确性和线程安全,避免了竞争和死锁。
转载地址:http://kpefk.baihongyu.com/