线程同步---条件变量

条件变量(cond):

为什么需要条件变量?

  1. 当一个线程互斥的访问某个变量时,它可能发现在其他线程改变该变量状态之前,它什么也做不了!(此时就是死锁,一种僵死状态)

我们需要一种机制,当互斥量锁住以后,当前线程还是无法完成自己的操作,那么就应该释放互斥量,让其他线程继续工作。
1. 可以用轮询机制,不停的查询你需要的条件;
2. 用条件变量机制;

条件变量函数:
(1)初始化

函数初始化
int pthread_cond_init(pthread_cond_t *restrict cont,const pthread_condattr_t *restrict attr);

参数:跟互斥量相似
cond: 要初始化的条件变量;
attr: 条件变量属性,一般设为NULL;
当然也可以用宏 : PTHREAD_CONT_INITALIZER 静态初始化

pthread_cond_t cond = PTHREAD_CONT_INITALIZER;

(2)等待条件满足

//非阻塞,
int pthread_cond_timedwite(pthread_conda_t *restrict cond,pthread_mutex_t *restrict mutex,const struct timespec *restrict abstime);
//阻塞
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);

参数:
cond: 要在这个条件变量上等待;
mutex: 互斥量
abstime: 指定等待时间,如果在规定时间没有通知,返回 ETIMEDOUT错误;
pthread_cond_wait()做的三件事:
1,释放锁—->2,等待锁—->3,收到条件信息,尝试获取锁

(3)唤醒等待

//唤醒改条件变量上的所有线程
int pthread_cond_broadcast(pthread_cond_t *cond);
//至少唤醒一个等待的线程
int pthread_cond_signal(pthread_cond_t *cond);

(4)销毁条件变量

int pthread_cond_destroy(pthread_cond_t *cond);

例子:
有全局变量money;主线程减小money,当money等于0时,子线程使money加上200;

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

pthread_cond_t cond;    //定义条件变量
pthread_mutex_t mutex;  //定义互斥量

int money;  //定义全局资源
//线程函数
void* pthread_func(void* arg)
{
    while(1)
    {
        pthread_mutex_lock(&mutex); //上锁

        while(money>0)
        {
            printf("让子线程等待money等于0\n");
            pthread_cond_wait(&cond,&mutex);    //等待(阻塞)
        }

        //让子线程进入临界区查看
        if(money==0)
        {
            money += 200;
            printf("子线程money=%d\n",money);
        }

        //解锁
        pthread_mutex_unlock(&mutex);

        sleep(1);
    }
    return NULL;
}


int main()
{
    pthread_t tid;

    pthread_mutex_init(&mutex,NULL); //初始化互斥量
    pthread_cond_init(&cond,NULL);   //初始化条件变量

    pthread_create(&tid,NULL,pthread_func,NULL);//创建子线程

    money=1000;
    while(1)
    {
        //上锁
        pthread_mutex_lock(&mutex);

        if(money>0)
        {
            money-=100;
            printf("主线程:money=%d\n",money);
        }
        //解锁
        pthread_mutex_unlock(&mutex);

        //如果money=0就通知子线程
        if(money==0)
        {
            printf("通知子线程>:\n");
            pthread_cond_signal(&cond); //唤醒
        }

        sleep(1);
    }

    return 0;
}

结果:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/prefect_boy/article/details/79945463