zoukankan      html  css  js  c++  java
  • 条件变量 学习笔记

    条件变量的意义在于:

    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 }
  • 相关阅读:
    流程控制
    数据类型和运算符
    抽奖
    蓝桥杯 第五届
    python下编译py成pyc和pyo
    Django中提示TemplateDoesNotExist?
    Ubuntu16.04 apache2 wsgi 部署django
    Ubuntu 14.04下Django+MySQL安装部署全过程
    LVM原理及PV、VG、LV、PE、LE关系图
    SQLServer2008-镜像数据库实施手册(双机)SQL-Server2014同样适用
  • 原文地址:https://www.cnblogs.com/superPerfect/p/3663395.html
Copyright © 2011-2022 走看看