POSIX 条件变量 - C语言实例使用理解

目录

基本理解

代码实现

逻辑分析


 

基本理解

  • 条件变量是用于线程同步,关注对象是共享数据状态的变化,用来协调各个线程合作完成某个任务。当一个动作需要另外一个动作完成时才能进行时,即:当一个线程的行为依赖于另外一个线程对共享数据状态的改变时,这时候就可以使用条件变量。
  • 条件变量是与互斥量相关联的一种用于多线程之间关于共享数据状态改变的通信机制。
  • 条件变量与互斥量一起使用的时候,允许线程以无竞争的方式等待特定的条件发生。
  • 条件变量是由互斥量保护的,线程在改变条件变量状态前必须先锁住互斥量。

pthread_cond_wait() 执行时内部会解锁互斥锁,然后等待条件变量被其他线程激活,被激活后会再自动加锁(在其他线程释放互斥锁之后),并重新判断条件变量阻塞条件是否成立,成立重新挂起,不成立则继续往下执行。

线程调用pthread_cond_wait() 这个函数之后,内核会做下面这些事:

1,拿到锁的线程,把锁暂时释放;

2,线程休眠,进行等待;

3,线程等待通知,要醒来。(重新获取锁)

线程库将上面三步做成了原子性操作;

代码实现

思路:使用信号量cond和互斥锁lock,创建两个同优先级线程 thread_a, thread_b 均使用互斥锁完成资源互斥访问,thread_a 以条件变量作为等待条件,thread_b 完成条件变量的释放,具体代码实现如下,为方便查看程序运行过程,代码内部添加了几处标记打印。

#include <stdio.h>
#include <pthread.h>
/*********************************************************************************************************
  全局变量定义
*********************************************************************************************************/
static pthread_mutex_t lock;
static pthread_cond_t  cond;
static int count = 0;
/*********************************************************************************************************
** 函数名称: thread_a
** 功能描述: 线程函数
** 输 入  : arg  传入的参数
** 输 出  : NONE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static void *thread_a (void *arg)
{

    while (1) {
        pthread_mutex_lock(&lock);//1 getlock

        printf("thread_a()1: count = %d\n", count);

        pthread_cond_wait(&cond, &lock);//2 postlock,waitcond //6 getcond, getlock

        printf("thread_a()2: count = %d\n", count);

        pthread_mutex_unlock(&lock);//7 postlock
    }

    return  (NULL);
}
/*********************************************************************************************************
** 函数名称: thread_b
** 功能描述: 线程函数
** 输 入  : arg  传入的参数
** 输 出  : NONE
** 全局变量:
** 调用模块:
*********************************************************************************************************/
static void *thread_b (void *arg)
{
    while (1) {
        pthread_mutex_lock(&lock);//3 getlock

        count++;
        printf("thread_b()1: count = %d\n", count);

        pthread_cond_broadcast(&cond);//4 postcond

        printf("thread_b()2: count = %d\n", count);

        pthread_mutex_unlock(&lock);//5 postlock

        sleep(1);//确保 thread_b 释放互斥锁后 thread_a 可以获得锁资源,否则 thread_b 将一直持有锁
    }

    return  (NULL);
}

/*********************************************************************************************************
** 函数名称: main
** 功能描述: 主函数
** 输 入  : argc,argv
** 输 出  : ERROR
** 全局变量:
** 调用模块:
*********************************************************************************************************/
int main (int argc, char *argv[])
{
    pthread_t           threada_tid;
    pthread_t           threadb_tid;
    int                 ret;

    ret = pthread_mutex_init(&lock, NULL);
    if (ret != 0) {
        fprintf(stderr, "mutex create failed.\n");
        return  (-1);
    }

    ret = pthread_cond_init(&cond, NULL);
    if (ret != 0) {
        fprintf(stderr, "cond create failed.\n");
        return  (-1);
    }

    ret = pthread_create(&threada_tid, NULL, thread_a, NULL);
    if (ret != 0) {
        fprintf(stderr, "pthread create failed.\n");
        return  (-1);
    }

    ret = pthread_create(&threadb_tid, NULL, thread_b, NULL);
    if (ret != 0) {
        fprintf(stderr, "pthread create failed.\n");
        return  (-1);
    }

    pthread_join(threada_tid, NULL);
    pthread_join(threadb_tid, NULL);

    pthread_cond_destroy(&cond);
    pthread_mutex_destroy(&lock);

    return  (0);
}

逻辑分析

先上程序运行结果吧:

 程序运行的逻辑分析我根据理解画了个图(个人理解,有误可以在评论踢我一脚告知 ─=≡Σ(((つ•̀ω•́)つ),关于两个线程内代码的运行顺序我已经加在上方代码的注释里面了,可以查看参考。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值