pthread_mutex_t & pthread_cond_t 总结( 二 )


当我们通过 pthread_mutex_init() 初始化互斥量后,接下来就是上锁(pthread_mutex_lock)和解锁(pthread_mutex_unlock)操作了 。
2.3 上锁 & 解锁
上锁解锁函数原型pthread_mutex_lock(pthread_mutex_t *mutex);int pthread_mutex_unlock(pthread_mutex_t *mutex);头  文  件#include <pthread.h>#include <pthread.h>返  回  值成功返回 0,失败返回错误码成功返回 0,失败返回错误码让我们来梳理一下互斥量的使用流程:

  1. 通过 pthread_mutex_init() 购买一把锁
  2. 通过 pthread_mutex_lock() 加锁
  3. 通过 pthread_mutex_unlock() 解锁
下面让我们通过「锁」操作修改一下上述代码:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 静态初始化锁void *func1(void *arg){    pthread_mutex_lock(&mutex);    puts("线程 th1 抢到锁");    puts("线程 th1 开始执行 giNum++");    int i;    for (i = 1; i <= MAX; i++)    {        giNum++;    }    pthread_mutex_unlock(&mutex);    return NULL;}void *func2(void *arg){    pthread_mutex_lock(&mutex);    puts("线程 th2 抢到锁");    puts("开始执行 giNum++");    int i;    for (i = 1; i <= MAX; i++)    {        giNum *= 2;    }    pthread_mutex_unlock(&mutex);    return NULL;}此时,再次运行程序,你会发现不管运行多少次,结果都是 \(giNum = 2\times10^7\) 。
下面我们对上面的代码做个简单的修改,将 func2 中的giNum++操作修改为giNum *= 2,
三、条件变量3.1 为什么要使用条件变量如果没有条件变量,那么我们等待一个条件满足则会是下面这样的模型:
pthread_mutex_t &amp; pthread_cond_t 总结

文章插图
  • 首先加锁进入临界区去查看条件是否满足,不满足则解锁离开临界区,睡眠一段时间再继续循环判断 。
在这种情况下如果刚离开临界区,条件变为满足,那么线程必须还要等一段时间重新进入临界区才能知道条件满足(如果在这段时间内,条件依旧一直保持满足的话);如果这一小段时间条件又变为了不满足,那么这个线程还要继续循环判断,不断地加锁解锁(会影响使用同一把锁的其他线程),还不能第一时间收到条件满足 。
这种模型既费时又开销大 , 所以条件变量的产生 , 正是为了不循环加锁解锁,并且第一时间收到条件满足的通知 。
3.2 条件变量函数介绍3.2.1 pthread_cond_t条件变量使用特定的数据类型:pthread_cond_t 。使用条件变量前要先初始化,初始化又分为静态初始化和动态初始化:
  • 静态初始化:pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
  • 动态初始化:pthread_cond_init(&cond, NULL);
静态初始化的条件变量只能拥有默认的条件变量属性,不能设置其他条件变量属性 。
3.2.2 pthread_cond_init函数原型:int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);
头  文  件:#include <pthread.h>
功         能:对条件变量初始化
返  回  值:成功返回 0 , 失败返回错误码
参数介绍:
  1. cond:需要初始化的条件变量
  2. attr:初始化时条件变量的属性,一般置为 NULL , 表示使用默认属性
3.2.3 pthread_cond_destory函数原型:int pthread_cond_destroy(pthread_cond_t *cond);
头  文  件:#include <pthread.h>
功         能:对条件变量反初始化(在条件变量释放内存之前)
返  回  值:成功返回 0,失败返回错误码
参数介绍:需要反初始化的条件变量
备注:此函数只是反初始化互斥量,并没有释放内存空间 。如果互斥量是通过 malloc 等函数申请的,那么需要在 free 掉互斥量之前调用 pthread_mutex_destroy 函数

推荐阅读