线程安全----条件变量

条件变量

      条件变量是另一种逻辑稍微复杂一点点的同步互斥机制,他必须跟互斥锁一起配合使

用,他的应用场景也是非常常见的,先来看一个例子:
 
     小楠是一名在校学生,每个月都会从父母那里得到一笔生活费。现在她的钱花光了,想
要去取钱。但是很显然取钱这样的事情不是想干就能干的,前提是卡里必须得有钱才行!于
是小楠拿起手机一查发现:余额为¥ 0 。现在她除了干瞪眼,唯一能干的事情也许只有一件:
等。等到她爸妈汇了钱打电话通知她为止。
       
      但更进一步,即便是她爸妈汇了钱也打了电话通知了她,此刻她也不能一定保证能取到
钱,因为与此同时她的众多兄弟姐妹(统统共用一个银行账号)很可能已经抢先一步将钱悉
数取光了!因此当小楠收到爸妈的电话之后,需要再次确认是否有钱,才能取钱。

      上图中,线程一旦发现余额为 0,就会进入等待睡眠,与此同时必须先释放互斥锁,如

果带着锁去睡大觉,那么结果是谁也别想修改余额,大家都进入无限期的阻塞之中,相反从
等待队列中出来的时候必须先持有互斥锁,因为出来后又要马上访问余额这个共享资源的。
   
     特别注意的是,有两把锁头是在框框里面的,这表示当一条线程进入某个条件变量的等
待队列中等待,以及从该等待队列中出来时,分别对互斥锁的解锁和加锁都是自动完成的,
这是为什么说条件变量跟互斥锁是配套使用的原因。

#include<stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

pthread_cond_t cond;
pthread_mutex_t lock;
int num=0;
void *function(void *arg)
{
    char *msg=(char *)arg;
   
     while (1)
   {
   
    if (num<100)
    {
      pthread_mutex_lock(&lock);
      printf("%s添加互斥锁成功!准备取钱\n",msg);
        //如果金额不足,则会进入条件变量的队列中等待
        //进入之前该函数会帮我们把lock互斥锁解开,以便存钱
       pthread_cond_wait(&cond, &lock);
    }
    num-=100;
    printf("我是%s号线程,目前余额%d\n",msg,num);
      pthread_mutex_unlock(&lock);
      sleep(10);   
  }
}

int main(int argc, char const *argv[])
{
    //初始化条件变量 
    pthread_cond_init(&cond, NULL);

    //初始化互斥锁 
     pthread_mutex_init(&lock,NULL);

    pthread_t thread1;
    pthread_t thread2;
    pthread_t thread3;
    pthread_t thread4;
     pthread_create(&thread1, NULL,function, "1");   
     pthread_create(&thread2, NULL,function, "2");   
     pthread_create(&thread3, NULL,function, "3"); 
     pthread_create(&thread4, NULL,function, "4"); 

     while (1)
     {
       //作为父母,时刻关注账号中的金钱
       if(num<100)
       {
          printf("余额不足,准备转帐!\n");
          pthread_mutex_lock(&lock);
          printf("main添加互斥锁成功!\n");
                    //如果小于100,自觉存钱
                    num+=100;
                    printf("微信转账100块\n");
            pthread_mutex_unlock(&lock);
          pthread_cond_signal(&cond);
          printf("成功唤醒所有孩子!\n");
        
          printf("解锁.....\n");
          sleep(1);
       }
     }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_52467164/article/details/127563233
今日推荐