Thread safety----condition variables

condition variable

      Condition variables are another synchronization mutex mechanism with slightly more complicated logic. They must be used together with mutex locks.

Its application scenarios are also very common. Let’s look at an example first:
 
     Xiaonan is a student at school and receives a living allowance from her parents every month. Now that her money is gone, she thinks
Going to withdraw money. But obviously, withdrawing money is not something you can do if you want to. The premise is that there must be money in the card! At
It was Xiaonan who picked up her phone and checked it out: the balance was ¥ 0 . Now besides staring, the only thing she can do may be one thing:
wait. Wait until her parents have wired the money and call her to inform her.
       
      But further, even if her parents remitted the money and called her to notify her, she could not guarantee that she would get it at this moment.
money, because at the same time, her many brothers and sisters (all sharing a bank account) may have been the first to get the money.
Count them all! Therefore, when Xiaonan received a call from her parents, she needed to confirm again whether she had money before she could withdraw the money.

      In the above figure, once the thread finds that the balance is 0 , it will enter waiting sleep. At the same time, the mutex lock must be released first, such as

If you go to bed with a lock, no one will be able to modify the balance, and everyone will be blocked indefinitely. On the contrary, no one will be able to modify the balance.
When waiting to come out of the queue, you must first hold the mutex lock, because you need to access the shared resource balance immediately after coming out.
   
     Pay special attention to the fact that there are two locks inside the frame, which means that when a thread enters the wait state of a certain condition variable,
When waiting in the waiting queue and coming out of the waiting queue, the unlocking and locking of the mutex are automatically completed.
This is why condition variables and mutex locks are used together.

#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;
}

Guess you like

Origin blog.csdn.net/m0_52467164/article/details/127563233