16、操作系统——条件变量

目录

1、作用

2、 API

(1)pthread_cond_init、pthread_cond_destory(初始化、销毁条件变量)

(2)pthread_cond_timewait、pthread_cond_wait(进入条件变量等待队列、同时对获取配套的互斥锁)

(3)pthread_cond_broadcast、pthread_cond_signal

 3、互斥锁+条件变量的使用

(1)主线程解锁后唤醒所有线程

(2)主线程解锁后唤醒一个线程

1、作用

当有多个线程需要获得同一个资源进行操作的时候,如果当前资源量未空, 那么就需要让所有来 获取资源的线程进入一个条件变量的等待队列中进行等待,等待资源数据到达, 当资源数据到达的时 候条件变量则可以选择从队列中唤醒线程进行读取资源(唤醒可以唤醒一个或多个)。

2、 API

(1)pthread_cond_init、pthread_cond_destory(初始化、销毁条件变量)

(2)pthread_cond_timewait、pthread_cond_wait(进入条件变量等待队列、同时对获取配套的互斥锁)

(3)pthread_cond_broadcast、pthread_cond_signal

 3、互斥锁+条件变量的使用

(1)主线程解锁后唤醒所有线程

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

pthread_cond_t cond ;
pthread_mutex_t lock;

int num = 0 ;

void * FUNC(void * arg )
{
    int num_1 = (int ) arg ;
    while(1)
    {
        pthread_mutex_lock(&lock); // 添加互斥锁, 准备取钱(阻塞等待)
        while( num < 100 )
        {
            // 如果金额不足,则会进入条件变量的队列中等待
            // 进入之前该函数会帮我们把 lock 互斥锁先解开,以便父母存钱
            // 当金额被更新之后,该函数会帮我们把Lock 互斥锁添加
            pthread_cond_wait(&cond , &lock );
        }
        num -= 100 ;
        printf("我是%d号线程, 我取完金子,目前余额是%d\n" , num_1 , num );
        pthread_mutex_unlock(&lock);  
        sleep(1);
    }
}


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_t thread5 ;
    pthread_t thread6 ;
    
    pthread_create(&thread1, NULL, FUNC , (void *)1 ); 
    pthread_create(&thread2, NULL, FUNC , (void *)2 ); 
    pthread_create(&thread3, NULL, FUNC , (void *)3 ); 
    pthread_create(&thread4, NULL, FUNC , (void *)4 ); 
    pthread_create(&thread5, NULL, FUNC , (void *)5 ); 
    pthread_create(&thread6, NULL, FUNC , (void *)6 ); 

    while(1)
    {
        // 作为父母,我们应该时刻关注账号中是否有足够的银子
        if ( num < 100 )
        {
            // 如果小于100块钱, 我们就自觉存钱
            printf("账户余额不足开始等待锁资源进行存钱....\n");
            pthread_mutex_lock(&lock);
            printf("添加互斥锁, 准备存钱!!\n");

            num += 300 ;
            printf("微信转账300块!! \n") ;
            sleep(1);

            // 唤醒所有在队列中等待的孩子们
            pthread_cond_broadcast(&cond);
            printf("唤醒所有的孩子!!!\n");
            // 解开互斥锁
            pthread_mutex_unlock(&lock);
            printf("解开互斥锁!!\n");
        }       
    }
    return 0;
}

 (2)主线程解锁后唤醒一个线程

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

pthread_cond_t cond ;
pthread_mutex_t lock;

int num = 0 ;

void * FUNC(void * arg )
{
    int num_1 = (int ) arg ;
    printf("我是%d号线程\n" , num_1 , num );

    while(1)
    {
        pthread_mutex_lock(&lock); // 添加互斥锁, 准备取钱(阻塞等待)
        while( num < 100 )
        {
            // 如果金额不足,则会进入条件变量的队列中等待
            // 进入之前该函数会帮我们把 lock 互斥锁先解开,以便父母存钱
            // 当金额被更新之后,该函数会帮我们把Lock 互斥锁添加
            pthread_cond_wait(&cond , &lock );
        }

        num -= 100 ;
        printf("我是%d号线程, 我取完金子,目前余额是%d\n" , num_1 , num );
        pthread_mutex_unlock(&lock);  
        sleep(1);
    }

}


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_t thread5 ;
    pthread_t thread6 ;
    

    pthread_create(&thread1, NULL, FUNC , (void *)1 ); 
    pthread_create(&thread2, NULL, FUNC , (void *)2 ); 
    pthread_create(&thread3, NULL, FUNC , (void *)3 ); 
    pthread_create(&thread4, NULL, FUNC , (void *)4 ); 
    pthread_create(&thread5, NULL, FUNC , (void *)5 ); 
    pthread_create(&thread6, NULL, FUNC , (void *)6 ); 


    while(1)
    {
        // 作为父母,我们应该时刻关注账号中是否有足够的银子
        if ( num < 100 )
        {
            // 如果小于100块钱, 我们就自觉存钱
            printf("账户余额不足开始等待锁资源进行存钱....\n");
            pthread_mutex_lock(&lock);
            printf("添加互斥锁, 准备存钱!!\n");

            num += 100 ;

            printf("微信转账100块!! \n") ;

            // sleep(1);

            // 唤醒所有在队列中等待的孩子们
            // pthread_cond_broadcast(&cond);
            pthread_cond_signal(&cond);
            printf("唤醒一个孩子!!!\n");
            // 解开互斥锁
            pthread_mutex_unlock(&lock);
            printf("解开互斥锁!!\n");
        }
        
    }
    
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45981798/article/details/129889434