文章目录
- 一、cond 介绍
- 二、cond 基本函数
- 1. `int pthread_cond_init(pthread_cond_t *cv, const pthread_condattr_t *cattr);`
- 2. `int pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex);`
- 3. `int pthread_cond_signal(pthread_cond_t *cv);`
- 4. `int pthread_cond_timedwait(pthread_cond_t *cv, pthread_mutex_t *mp, const structtimespec * abstime);`
- 5. `int pthread_cond_broadcast(pthread_cond_t *cv);`
- 6. `int pthread_cond_destroy(pthread_cond_t *cv);`
- 三、cond 使用示例
一、cond 介绍
cond 的使用总是和互斥锁及共享资源联系在一起的。线程首先锁住互斥锁,然后检验共享资源的状态是否处于可使用的状态。如果不是,那么线程就要等待条件变量。要指向这样的操作就必须在等待的时候将互斥锁解锁,以便其他线程可以访问共享资源并改变其状态
二、cond 基本函数
1. int pthread_cond_init(pthread_cond_t *cv, const pthread_condattr_t *cattr);
初始化一个条件变量,当参数cattr为空指针时,创建的是一个缺省的条件变量
可以用宏 pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
来初始化条件变量,使其具有缺省属性
2. int pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex);
- 当前线程1在wait内部释放互斥锁,然后阻塞等待条件变量,等待其它线程调用
pthread_cond_signal/pthread_cond_broadcast
函数将自己唤醒 - 线程2获取到互斥锁(a步wai内部释放了互斥锁),调用
pthread_cond_signal/pthread_cond_broadcast
唤醒阻塞等待条件变量的线程1 - 线程1被signal唤醒后,wait内部重新获取互斥锁,但此时线程2还没有释放互斥锁,因此线程1被唤醒后继续阻塞等待获取互斥锁
- 线程2调用signal后继续执行count++,然后释放互斥锁
- 线程1获取到互斥锁(d步线程2释放了互斥锁),wait函数返回,继续往下执行counter–,然后释放互斥锁
3. int pthread_cond_signal(pthread_cond_t *cv);
释放被阻塞在条件变量上的一个线程,如果没有线程被阻塞在条件变量上,那么调用pthread_cond_signal()
将没有作用
4. int pthread_cond_timedwait(pthread_cond_t *cv, pthread_mutex_t *mp, const structtimespec * abstime);
函数到了一定的时间,即使条件未发生也会解除阻塞
5. int pthread_cond_broadcast(pthread_cond_t *cv);
唤醒所有被 pthread_cond_wait
函数阻塞在条件变量上的线程。当没有线程阻塞在这个条件变量上时,pthread_cond_broadcast
函数无效。由于 pthread_cond_broadcast
函数唤醒所有阻塞在条件变量上的线程,这些线程被唤醒后将再次竞争互斥锁(wait函数b步)
6. int pthread_cond_destroy(pthread_cond_t *cv);
释放条件变量
三、cond 使用示例
#include <unistd.h>
#include <pthread.h>
#include <iostream>
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int variable = 0;
void* consumer(void* arg)
{
int num = *((int*)arg);
while (1)
{
pthread_mutex_lock(&mutex);
while (variable == 0)
{
cout << "consumer " << num << " begin wait condition" << endl;
pthread_cond_wait(&cond, &mutex); // unlock mutex, blocked on cond
}
cout << "consumer " << num << " end wait condition" << endl;
cout << "consumer " << num << " consume product" << endl;
variable--;
pthread_mutex_unlock(&mutex);
sleep(1);
}
return NULL;
}
void* producer(void* arg)
{
while (1)
{
pthread_mutex_lock(&mutex);
variable++;
pthread_cond_signal(&cond); // wakeup threads waiting on cond
cout << "producer signal consumer by condition variable" << endl;
pthread_mutex_unlock(&mutex);
sleep(3);
}
return NULL;
}
int main(void)
{
pthread_t threads[3];
for (int i = 0; i < 2; i++)
{
pthread_create(&threads[i], NULL, consumer, (void*)&i);
}
sleep(1);
pthread_create(&threads[2], NULL, producer, NULL);
for (int i = 0; i < 3; i++)
{
pthread_join(threads[i], NULL);
}
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
}