条件变量的意义在于:
1.多个线程对一个保护的资源进行控制的时候, 当一个线程A进入临界区,发现此时需要等待这个资源满足某个条件而阻塞。这个时候因为阻塞的地方是在临界区里面,所以其他线程也无法操纵这个资源使之满足A线程的条件,从而导致线程A永远阻塞在这里。
2.为了解决这个问题,可以使用条件变量
当线程A阻塞时,可以通过pthread_cond_wait来退出临界区,从而使其他线程能够进入临界区操纵资源,当线程A条件满足的时候,执行pthread_cond_signal来通知线程A,条件满足了,从而pthread_cond_wait返回,同时线程A又进入临界区。
3. while(pNum == 0) {pthread_cond_wait(&cond, &lock);} 使用while而不使用if的原因是,可能在某些情况会被假的信号唤醒,而不是真正满足了条件,这个时候就需要判断条件从而防止错误发生
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <errno.h> 5 #include <pthread.h> 6 #include <semaphore.h> 7 8 #define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE);} while(0) 9 10 int pNum = 0; 11 pthread_mutex_t lock; 12 pthread_cond_t cond; 13 void init() 14 { 15 int ret; 16 ret = pthread_mutex_init(&lock , NULL); 17 if(ret != 0) { 18 ERR_EXIT("pthread_init"); 19 } 20 ret = pthread_cond_init(&cond, NULL); 21 if(ret != 0) { 22 ERR_EXIT("pthread_cond_init"); 23 } 24 } 25 void *consumerFun(void *arg) 26 { 27 while(1) { 28 pthread_mutex_lock(&lock); 29 while(pNum == 0) { 30 printf("wait product exit... "); 31 pthread_cond_wait(&cond, &lock); 32 } 33 printf("already exit ... "); 34 pNum--; 35 printf("consumer pNum %d ", pNum); 36 pthread_mutex_unlock(&lock); 37 sleep(1); 38 } 39 return (void *)0; 40 } 41 void *producerFun(void *arg) 42 { 43 while(1) { 44 pthread_mutex_lock(&lock); 45 pNum++; 46 printf("producer product one :%d ", pNum); 47 pthread_cond_signal(&cond); 48 pthread_mutex_unlock(&lock); 49 sleep(3); 50 } 51 return (void *)0; 52 } 53 int main(int argc, char *argv[]) 54 { 55 int ret; 56 pthread_t producer; 57 pthread_t consumer; 58 init(); 59 ret = pthread_create(&producer, NULL, producerFun, NULL); 60 if(ret != 0) { 61 ERR_EXIT("pthread_create"); 62 } 63 ret = pthread_create(&consumer, NULL, consumerFun, NULL); 64 if(ret != 0) { 65 ERR_EXIT("pthread_create"); 66 } 67 pthread_join(producer, NULL); 68 pthread_join(consumer, NULL); 69 pthread_mutex_destroy(&lock); 70 pthread_cond_destroy(&cond); 71 return 0; 72 }