{
pthread_mutex_t mutex;
pthread_cond_t cond;
pthread_mutex_init (&mutex, NULL);
pthread_cond_init(&cond, NULL);
ret = pthread_create (&pt_1, NULL, (void *)pthread_func_1, NULL);
pthread_join (pt_1, NULL);
pthread_mutex_lock(&mutex);
pthread_mutex_unlock(&mutex);
pthread_cond_wait(&cond, &mutex);
pthread_cond_signal(&cond);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
}
1.互斥量的存在问题:
互斥量是线程程序必需的工具,但它们并非万能的。
如果线程正在等待共享数据内某个条件出现,它可以重复对互斥对象锁定和解锁,每次都会检查共享数据结构,以查找某个值。但这种繁忙查询的效率非常低。
可以让调用线程短暂地进入睡眠,比如睡眠三秒钟,但就无法最快作出响应。
需要的是:当线程在等待满足某些条件时使线程进入睡眠状态。一旦条件满足,就唤醒因等待满足特定条件而睡眠的线程。如果能够做到这一点,线程代码将是非常高效的,并且不会占用宝贵的互斥对象锁。
条件变量允许线程阻塞和等待另一个线程发送信号的方法,它常和互斥锁一起使用。
使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化。一旦其它的某个线程改变了条件变量,它将通知相应的条件变量唤醒一个或多个正被此条件变量阻塞的线程。这些线程将重新锁定互斥锁并重新测试条件是否满足。
此时,pthread_cond_wait() 调用还未返回。对互斥对象解锁会立即发生,但等待条件 mycond 通常是一个阻塞操作,这意味着线程将睡眠,在它苏醒之前不会消耗 CPU 周期。这正是我们期待发生的情况。
从线程的角度来看,它只是在等待 pthread_cond_wait() 调用返回。
假设另一个线程(称作“2 号线程”)锁定了 mymutex 并对已链接列表添加了一项。在对互斥对象解锁之后,2 号线程会立即调用函数 pthread_cond_broadcast(&mycond)。此操作之后,2 号线程将使所有等待 mycond 条件变量的线程立即苏醒。这意味着第一个线程(仍处于 pthread_cond_wait() 调用中)现在将苏醒。它对 mymutex 解锁,然后进入睡眠状态,等待 mycond 以接收 POSIX 线程“信号”。“信号”是来自 pthread_cond_signal() 或 pthread_cond_broadcast() 调用的信号)。
pthread_cond_wait() 没有立即返回, 重新锁定 mutex:
pthread_mutex_lock(&mymutex);
例子
a、建立两个线程1、2,两个线程分别访问共享资源,并进行加1操作,当共享资源<=3时,线程1挂起不操作,这时线程2工作,共享资源>3后,两者都工作。