条件变量

    科技2024-10-19  58

    三、条件变量。 1、 什么是条件变量? 线程因为某一个条件/情况不成立下,进入一个变量中等待,这个存放线程的变量就是条件变量。 条件变量一定要与互斥锁连用。

    2、条件变量的函数接口。 1)先定义一个条件变量。  -> 数据类型: pthread_cond_t    pthread_cond_t cond;

    2)初始化条件变量。  -> pthread_cond_init()  -> man 3 pthread_cond_init 动态初始化: 头文件:     #include <pthread.h>

    原型:         int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr);

    参数:     cond: 条件变量的地址。     cond_attr: 普通属性,填NULL。

    返回值:     成功:0     失败:非0

    静态初始化: pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

    3)如何进入条件变量中等待?   ->  pthread_cond_wait()  -> man 3 pthread_cond_wait 头文件:     #include <pthread.h>

    原型:     int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);

    参数:     cond:条件变量的地址。     mutex: 互斥锁的地址。  -> 进入条件变量中等待时,会自动解锁。

    返回值:     成功:0     失败:非0

    4)如何唤醒条件变量中等待的线程?  -> 线程离开条件变量时,会自动上锁。 广播:唤醒所有在条件变量中等待的线程。     --> pthread_cond_broadcast() 单播:随机唤醒一个在条件变量中等待的线程。 --> pthread_cond_signal()

    头文件:     #include <pthread.h>

    原型:     int pthread_cond_broadcast(pthread_cond_t *cond);     int pthread_cond_signal(pthread_cond_t *cond);

    参数:     cond:条件变量的地址。

    返回值:     成功:0     失败:非0

    5)销毁条件变量。  -> pthread_cond_destroy()  -> man 3 pthread_cond_destroy 头文件:     #include <pthread.h>

    原型:     int pthread_cond_destroy(pthread_cond_t *cond);

    参数:     cond:条件变量的地址。

    返回值:     成功:0     失败:非0

       练习4: 有5个小孩,每一个小孩任务都是拿200块,首先在银行卡里面存400块,有2个小孩可以拿到钱后退出,3个线程拿不到钱就进去条件变量中睡眠,5S再打400块之后,唤醒所有的小孩起来拿钱,4S再打200块,唤醒一个小孩起来。

    #include "head.h"

    //初始化互斥锁 pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;

    //初始化条件变量 pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

    int sum = 400;

    //线程: void *fun(void *arg) {     //1. 每一个线程访问临界资源(银行卡)之前,都必须先上锁。     pthread_mutex_lock(&m);          //2. 询问条件是否满足?     while(sum < 200)  //请问余额是不是<200     {         //3. 不能拿到钱就进去睡眠。         pthread_cond_wait(&cond,&m);     }

        //4. 能拿到钱就扣钱     printf("before money:%d\n",sum);     sum -= 200;     printf("after money:%d\n",sum);          //5. 解锁     pthread_mutex_unlock(&m);          //6. 走人     pthread_exit(NULL); }

    void *func_time(void *arg) {     int i;     for(i=0;i<100;i++)     {         printf("i = %d\n",i);         sleep(1);     } }

    int main(int argc,char *argv[]) {     //0. 倒数时间线程     pthread_t tid_time;     pthread_create(&tid_time,NULL,func_time,NULL);          //1. 由于5个线程任务一样,通过循环去创建线程。     int i;     pthread_t tid[5];     for(i=0;i<5;i++)     {         pthread_create(&tid[i],NULL,fun,NULL);     }          //2. 打400块     sleep(5);     pthread_mutex_lock(&m);     sum += 400;     printf("main thread + 400!\n");     pthread_mutex_unlock(&m);          //3. 唤醒所有小孩     sleep(2);     pthread_cond_broadcast(&cond); //只有2个小孩能拿到钱          //4. 打200块     sleep(3);     pthread_mutex_lock(&m);     sum += 200;     printf("main thread + 200!\n");     pthread_mutex_unlock(&m);

        //5. 唤醒一个小孩     sleep(2);     pthread_cond_signal(&cond);          //6. 接合线程     for(i=0;i<5;i++)     {         pthread_join(tid[i],NULL);     }          //7. 销毁资源     pthread_mutex_destroy(&m);     pthread_cond_destroy(&cond);          return 0; }

     

    Processed: 0.009, SQL: 8