linux 条件变量

条件变量的概述

条件变量不是锁,但它可以和互斥锁配合使用,互斥锁有两种状态:锁定和非锁定,但是互斥锁无法保证线程执行的先后顺序,这时就需要条件变量。

条件变量相关的函数

初始化一个条件变量

pthread_cond_init(pthread_cond_t * restrict cond,const pthread_condattr_t * restrict attr);

销毁一个条件变量

pthread_cond_destroy(pthread_cond_t * cond);

阻塞等待一个条件变量

pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t * restrict mutex)

在同一个线程里,互斥锁已经上锁,使用pthread_cond_wait(),会瞬间将已经上锁的mutex解锁,并阻塞线程,
当被其他线程唤醒时,该函数解除阻塞,对互斥锁加锁

限时等待一个条件变量

pthread_cond_timedwait(pthread_cond_t * restrict cond,pthread_mutex_t * restrict mutex
,const struct timespec * restrict abstime)

唤醒至少一个阻塞在条件变量上的线程

pthread_cond_signal(pthread_cond_t* cond);

唤醒全部阻塞在条件变量上的线程

pthread_cond_broadcast(pthread_cond_t * cond)

练习

使用条件变量实现生产者,消费者模型
cond.c

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

//定义一个链表节点类型
typedef struct node
{
        int data ;
        struct node * next;
}NODE;

pthread_mutex_t mutex;
pthread_cond_t cond;
NODE * head=NULL;

void *producer(void * arc)
{
        while(1)
        {
                //创建链表节点
                NODE* pnew=(NODE *)malloc(sizeof(NODE));
                //初始化节点
                pnew->data=rand()%1000;//0-999
                printf("producter data is %d\n",pnew->data);

                pthread_mutex_lock(&mutex);
                pnew->next=head;
                head=pnew;
                pthread_mutex_unlock(&mutex);
                //唤醒等待条件的线程
                pthread_cond_signal(&cond);
                sleep(rand()%3);//0-2

        }
        return 0;
}
void *customer(void * arc)
{
        while(1)
        {
                pthread_mutex_lock(&mutex);
                if(head==NULL)//如果共享区域没有数据,则解锁并等待唤醒
                {
                        pthread_cond_wait(&cond,&mutex);
                }
                NODE* pdel=NULL;
                pdel=head;
                head=pdel->next;
                pthread_mutex_unlock(&mutex);

                printf("customer data is %d\n",pdel->data);
                free(pdel);//释放被删除的节点内存
                pdel=NULL;//将删除的节点指针指向NULL,防止野指针

                sleep(rand()%3);

        }
        return 0;
}
int main()
{
        pthread_t id1,id2;
        //init mutex
        pthread_mutex_init(&mutex,NULL);
        //init condition
        pthread_cond_init(&cond,NULL);
        pthread_create(&id1,NULL,producer,NULL);
        pthread_create(&id2,NULL,customer,NULL);

        pthread_join(id1,NULL);
        pthread_join(id2,NULL);

}

请添加图片描述

条件变量的优点:

对比互斥锁,条件变量可以减少竞争。

如果直接使用mutex,除了生产者、消费者之间要竞争互斥量以外,消费者之间也需要竞争互斥量,但如果链表中没有数据,消费者之间竞争互斥锁是无意义的。有了条件变量机制以后,只有生产者完成生产,才会引起消费者之间的竞争。提高了程序效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值