多线程——条件变量的概念和实现

12 篇文章 0 订阅
8 篇文章 0 订阅

概念

条件变量,也称条件锁,是利用线程间共享的全局变量进行同步的一种机制,

主要包括两个动作:

1)一个线程等待"条件变量的条件成立"而挂起;

2)另一个线程使"条件成立"(给出条件成立信号)条件的检测是在互斥锁的保护下进行的如果一个条件为假,一个线程自动阻塞,并释放等待状态改变的互斥锁。

如果另一个线程改变了条件,它发信号给关联的条件变量,唤醒一个或多个等待它的线程,重新获得互斥锁,重新评价条件。

如果两进程共享可读写的内存,条件变量可以被用来实现这两进程间的线程同步

函数API

说明:

只有在没有线程在该条件变量上等待的时候才能注销这个条件变量,否则返回EBUSY。

因为Linux实现的条件变量没有分配什么资源,所以注销动作只包括检查是否有等待线程。 

 

 说明:函数将解锁mutex参数指向的互斥锁,并使当前线程阻塞在cv参数指向的条件变量上。

阻塞的线程,可以被以下条件唤醒

1)pthread_cond_signal函数

2)pthread_cond_broadcast函数

3)在被信号中断后被唤醒

 

说明:

1)必须在互斥锁的保护下使用相应的条件变量。否则对条件变量的解锁有可能发生在锁定条件变量之前,从而造成死锁。

2)如果没有线程被阻塞在条件变量上,那么调用pthread_cond_signal()将没有作用。 

 

 

说明:

1)函数唤醒所有被pthread_cond_wait函数阻塞在某个条件变量上的线程,参数cv被用来指定这个条件变量

2)当没有线程阻塞在这个条件变量上时,pthread_cond_broadcast函数无效。

3)由于pthread_cond_broadcast函数唤醒所有阻塞在某个条件变量上的线程,这些线程被唤醒后将再次竞争相应的互斥锁,所以必须小心使用pthread_cond_broadcast函数。 

 代码实例

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

unsignedcount=0;   //定义全局共享资源

//1.声明两个锁对象
pthread_mutex_t   mutex;
pthread_cond_t    cond;

//---------------消费者---------------------------------
void*decrement_count(void*arg)
{
    printf("[+]decrement_countbegintorun\n");
    //添加互斥锁
    pthread_mutex_lock(&mutex);
    /*条件变量不成立,调用pthread_cond_wait实现2件事:
    1.阻塞2.解锁*/
    while(count==0)
    {
        printf("[+]decrement_countcount==0\n");
        usleep(300000);
        pthread_cond_wait(&cond,&mutex);
    }
    //处理全局变量
    count--;
    pthread_mutex_unlock(&mutex);
    return(void*)1;
}
//---------------生产者---------------------------------
void*increment_count(void*arg)
{
    printf("[-]increment_countbegintorun\n");
    pthread_mutex_lock(&mutex);
    //创建条件成立,调用pthread_cond_signal(&cond);通知消费者
    if(count==0)
    {
        /*count做递减操作*/
        count=count+1;
        printf("[-]tid2:count=%d\n",count);
        pthread_cond_signal(&cond);
    }
    pthread_mutex_unlock(&mutex);
    return(void*)2;
}

int main()
{
    pthread_ttid1,tid2;
    /*初始化锁*/
    pthread_mutex_init(&mutex,NULL);
    /*初始化条件变量*/
    pthread_cond_init(&cond,NULL);

    tid1=pthread_create(&tid1,NULL,decrement_count,NULL);

    printf("[*]sucesstocreatedecrement_count\n");
    sleep(2);

    tid2=pthread_create(&tid2,NULL,increment_count,NULL);
    printf("[*]sucesstocreateincrement_count\n");
    sleep(10);

    //两种方式回收其子线程资源

    //1.连接2.分离
    /*3.销毁锁*/
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);

    printf("[*]mainthread,beginexit!\n");

    pthread_exit(0);
    return0;
}

 结构流程

1 初始化    锁    和    条件变量

消费者

上锁,这个锁是互斥锁,代表代码中的count变量只能被这个线程操作。

判断条件变量:这里是判断的全局变量count

这里假设count不满足,执行了条件变量的使用函数,里面的参数是条件变量和锁变量,意思是这个线程阻塞并等待条件变量,以及解锁,将count释放给其他线程。

然后陷入了等待

生产者

上锁

给消费者线程提供条件,改变count的值

发送唤醒信号pthread_cond_signal

解锁,注意这里要单独解锁。

又回到了消费者

消费者操作之后,解锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值