美文网首页程序员
条件变量中使用互斥锁的必要性

条件变量中使用互斥锁的必要性

作者: bazinga_dmc | 来源:发表于2020-05-17 22:04 被阅读0次

简单介绍一下使用条件变量时,增加互斥锁的必要性。pthread_cond_wait的API如下

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);

条件变量的用法就不具体介绍了,此处我们考虑的问题是增加mutex参数的必要性,先看看课本中的使用方法(只贴了主要的部分,包含生产者和消费者线程):

#include <stdio.h>
#include <pthread.h>
#define MAX 1000000000
pthread_mutex_t the_mutex;/*互斥锁*/
pthread_cond_t condc, condp;/*消费者和生产者条件变量*/
int buffer = 0;

void *producer(void *ptr)
{
  int i;
  
  for(i = 1; i <= MAX; i++)
  {
    pthread_mutex_lock(&the_mutex);
    while(buffer != 0)/*1*/
    {
      pthread_cond_wait(&condp, &the_mutex);/*2*/
    }
    buffer = i;
    pthread_cond_signal(&condc);
    pthread_mutex_unlock(&the_mutex);
  }
  pthread_exit(0);
}

void *consumer(void *ptr)
{
  int i;
  
  for(i = 1; i <= MAX; i++)
  {
    pthread_mutex_lock(&the_mutex);
    while(buffer == 0)/*3*/
    {
      pthread_cond_wait(&condc, &the_mutex);/*4*/
    }
    buffer = 0;
    pthread_cond_signal(&condp);
    pthread_mutex_unlock(&the_mutex);
  }
  pthread_exit(0);
}

线程在调用pthread_cond_wait并导致阻塞时会解锁互斥锁,解除阻塞并离开pthread_cond_wait时会加锁互斥锁。从代码中可以看到,该特性可以保证语句<1>和语句<3>中对buffer的访问和之后调用pthread_cond_wait导致的阻塞操作的原子性。

上面的解释可能不够直观,我们考虑一种错误的用法(去掉互斥锁),代码如下:

void *producer(void *ptr)
{
  int i;
  
  for(i = 1; i <= MAX; i++)
  {
    while(buffer != 0)/*1*/
    {
      pthread_cond_wait(&condp, NULL);/*2*/
    }
    buffer = i;
    pthread_cond_signal(&condc);
  }
  pthread_exit(0);
}

void *consumer(void *ptr)
{
  int i;
  
  for(i = 1; i <= MAX; i++)
  {
    while(buffer == 0)/*3*/
    {
      pthread_cond_wait(&condc, NULL);/*4*/
    }
    buffer = 0;
    pthread_cond_signal(&condp);
  }
  pthread_exit(0);
}

我们考虑一种可能的线程运行时序,如下所示(buffer初始值为0):

从图中可以看到在consumer线程对buffer进行访问并准备阻塞的时候,切换至producer线程运行,该线程更改了buffer的值,最终导致两个线程均被阻塞,发生死锁。

由此可以看出,在使用条件变量时,对需要判断的条件添加互斥锁的必要性。

相关文章

  • 条件变量中使用互斥锁的必要性

    简单介绍一下使用条件变量时,增加互斥锁的必要性。pthread_cond_wait的API如下 条件变量的用法就不...

  • Linux系统编程—条件变量

    条件变量是用来等待线程而不是上锁的,条件变量通常和互斥锁一起使用。条件变量之所以要和互斥锁一起使用,主要是因为互斥...

  • 线程同步与互斥

    Linux--线程编程 多线程编程-互斥锁 线程同步与互斥 互斥锁 信号量 条件变量 互斥锁 互斥锁的基本使用...

  • 条件变量

    条件变量: 条件变量本身不是锁!但它也可以造成线程阻塞。通常与互斥锁配合使用。给多线程提供一个会合的场所。为什么有...

  • 条件变量

    头文件:#include 与互斥锁不同,条件变量是用来等待而不是用来上锁的,条件变量本身不是锁!条件变量用来自动阻...

  • 多线程--锁

    本文主要介绍: 互斥锁 递归锁 读写锁 自旋锁 分布锁 条件变量 信号量 栅栏 一些常用锁的性能。 1. 互斥锁(...

  • [python] 线程间同步之条件变量Condition

    为什么需要条件变量 有了前面提到的互斥锁,为什么还需要条件变量呢,当然是由于有些复杂问题互斥锁搞不定了。Pytho...

  • Python多任务_线程

    简单使用 多线程共享全局变量-互斥锁

  • Linux线程同步

    Linux下提供了多种方式来处理线程同步,最常用的是互斥锁、条件变量和信号量。 Linux线程同步-----互斥锁...

  • linux常见的三种线程同步方式是什么?

    Linux系统中,实现线程同步的方式大致分为六种,其中包括:互斥锁、自旋锁、信号量、条件变量、读写锁、屏障。其中最...

网友评论

    本文标题:条件变量中使用互斥锁的必要性

    本文链接:https://www.haomeiwen.com/subject/ceyeohtx.html