//等待条件int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restric mutex);1:把调用线程放到所等待条件的线程列表上2:对传进来已经加过锁的互斥量解锁3:线程进入休眠状态等待被唤醒注:1、2步为原子操作//通知条件int pthread_cond_signal(pthread_cond_t *cond);1:通知指定条件已经满足2:等待线程重新锁定互斥锁3:等待线程需要重新测试条件是否满足
1 #include <iostream> 2 #include <queue> 3 #include <stdlib.h> 4 #include <unistd.h> 5 #include <pthread.h> 6 7 using std::cout; 8 using std::endl; 9 using std::queue;10 11 #define N 10012 #define ST 1013 14 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;15 pthread_cond_t ready = PTHREAD_COND_INITIALIZER;16 17 queue<int> que;18 19 void* threadPRoducer(void* arg)20 {21 while(true)22 {23 sleep(rand() % ST);24 25 cout << "Produce try in.../n";26 pthread_mutex_lock(&lock);27 cout << "Produce in!/n";28 int source = rand() % N;29 cout << "Produce " << source << endl;30 que.push(source);31 pthread_mutex_unlock(&lock);32 cout << "Produce out/n";33 34 pthread_cond_signal(&ready);35 }36 }37 38 void* threadConsumer(void* arg)39 {40 while(true)41 {42 sleep(rand() % ST);43 44 cout << "Consum try in.../n";45 pthread_mutex_lock(&lock);46 cout << "Consum in!/n";47 while(que.empty())48 {49 pthread_cond_wait(&ready, &lock);50 cout << "Consum from sleep/n";51 }52 cout << "Consum " << que.front() << endl;53 que.pop();54 pthread_mutex_unlock(&lock);55 cout << "Consum out/n/n";56 }57 }58 59 int main(void)60 {61 pthread_t tProducer, tConsumer; 62 pthread_create(&tProducer, NULL, threadProducer, NULL);63 pthread_create(&tConsumer, NULL, threadConsumer, NULL);64 65 pthread_join(tProducer, NULL);66 pthread_join(tConsumer, NULL);67 68 exit(0);69 }生消看到倒数的三四行,消费者进去了,发现没有数据了,则睡眠了,然后生产者进去生产了。
#include <iostream>#include <stdlib.h>#include <unistd.h>#include <pthread.h>using std::cout;using std::endl;pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t ready = PTHREAD_COND_INITIALIZER;int data = 0;void* threadProducer(void* arg){ int i; for(i = 1; i < 22; i++) { sleep(1); if(i % 3 != 0) { cout << "thread1:" << i << endl; } else { pthread_mutex_lock(&lock); data = i; pthread_mutex_unlock(&lock); pthread_cond_signal(&ready); } }}void* threadConsumer(void* arg){ while(true) { pthread_mutex_lock(&lock); while(data == 0) //no data pthread_cond_wait(&ready, &lock); cout <<"thread2:" << data << endl; if(data == 21) break; else data = 0; //empty data pthread_mutex_unlock(&lock); }}int main(void){ pthread_t tProducer, tConsumer; pthread_create(&tProducer, NULL, threadProducer, NULL); pthread_create(&tConsumer, NULL, threadConsumer, NULL); pthread_join(tProducer, NULL); pthread_join(tConsumer, NULL); exit(0);}3打印
程序大致这样:线程1中的循环,如果i不是3的倍数就自己打印了,如果是的话,把这个数放到一个地方(由于这个地方可以被线程2发现,所以要加锁访问),然后唤醒等待数据的线程2(如果线程2还没有在等待,那么这个唤醒则丢失,这是个bug,见下),线程2被唤醒后,消费了这个3的倍数,清空数据区。
上面提到,如果唤醒线程2的消息没有被收到,则bug。看下面的代码,也就多了38一行,让线程2睡了一会,就在它睡觉的那么一会,线程1把3的倍数往那里一扔就走了,自己再继续下两个不是3倍数的数字,这就直接输出了下面两个数字,又到了3倍数,又扔过去覆盖了之前数字:1 #include <iostream> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <pthread.h> 5 6 using std::cout; 7 using std::endl; 8 9 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;10 pthread_cond_t ready = PTHREAD_COND_INITIALIZER;11 12 int data = 0;13 14 void* threadProducer(void* arg)15 {16 int i;17 for(i = 1; i < 22; i++)18 { 19 sleep(1);20 21 if(i % 3 != 0)22 {23 cout << "thread1:" << i << endl;24 }25 else26 {27 pthread_mutex_lock(&lock);28 data = i;29 pthread_mutex_unlock(&lock);30 31 pthread_cond_signal(&ready);32 } 33 }34 }35 36 void* threadConsumer(void* arg)37 {38 sleep(20);39 while(true)40 {41 pthread_mutex_lock(&lock);42 while(data == 0) //no data43 pthread_cond_wait(&ready, &lock);44 cout <<"thread2:" << data << endl;45 if(data == 21)46 break;47 else48 data = 0; //empty data49 pthread_mutex_unlock(&lock);50 }51 }52 53 int main(void)54 {55 pthread_t tProducer, tConsumer; 56 pthread_create(&tProducer, NULL, threadProducer, NULL);57 pthread_create(&tConsumer, NULL, threadConsumer, NULL);58 59 pthread_join(tProducer, NULL);60 pthread_join(tConsumer, NULL);61 62 exit(0);63 }bug
//下面是生产者pthread_mutex_lock(&lock); //加锁访问临界区/*在这里生产数据*/pthread_mutex_unlock(&lock); //解锁 pthread_cond_signal(&ready); //通知消费者//下面是消费者pthread_mutex_lock(&lock); //加锁访问临界区while(没有待消费数据) pthread_cond_wait(&ready, &lock); //睡在这里,等待被唤醒/*被叫醒了,在这里消费数据*/pthread_mutex_unlock(&lock); //解锁
新闻热点
疑难解答