多线程编程2--线程的同步和互斥

本文详细介绍了多线程编程中的线程同步和互斥概念,包括互斥量防止数据不一致,条件变量实现线程同步,信号量控制资源访问,以及读写锁提高并行性。通过具体的示例和代码解释了这些同步机制的使用,如生产者消费者模型和环形队列的应用。
摘要由CSDN通过智能技术生成

当多个线程共享相同的内存时,需要确保每个线程看到一致的数据视图。

如果每个线程内部的变量其他线程都不会访问到,那么就不存在一致性问题;
如果变量是只读的,那么多个线程同时访问它也不存在不一致性问题;
但是,一旦一个变量是可写,当一个线程对它进行修改的时候,其他有可能对它进行读取或者写入操作从而导致数据不一致的问题。此时就需要同步机制来保证。

APUE上给出一个例子:

这里写图片描述

由于递增操作不是原子性的,因此不可避免的会出现上述数据不一致的问题。


1.互斥量

我们可以通过pthread库提供的互斥接口来保护数据,确保在同一时间只有一个线程访问这个数据。互斥量(mutex)本质上是一把锁,当我们访问共享资源对互斥量加锁,访问资源对互斥量解锁。对互斥量加锁后,任何试图向对该互斥量加锁的线程都会阻塞直到该锁被释放。

考虑多个线程访问一个数据,每个线程在访问数据之前都会先访问该互斥量,如果该互斥量已经加锁则阻塞,不然就对该互斥量加锁再去访问实际的数据。当有多线程因为互斥量加锁被阻塞时,一旦锁释放了,这些阻塞的线程都会运行起来,此时,第一个线程再去加锁互斥量访问数据,其他线程只能再次等待。

这里写图片描述

这里写图片描述

下面是一个关于引用计数的实例,其中count记为引用对象的个数,要求是对于count++,count–必须只有一个线程能访问,且只有当count == 0才释放资源。

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>
#include<sys/types.h>

typedef struct Counter
{
    int count;
    pthread_mutex_t mutex;
}Counter;

void Init(Counter* pc);
void Inc(Counter* pc);
void Dec(Counter* pc);

int main()
{

    Counter* pc = (Counter*)malloc(sizeof(Counter));
    if (pc == NULL)
        exit(-1);
    Init(pc);
    //...
    //...

    return 0;
}

void Init(Counter* pc)
{
    pc->count = 1;
    pthread_mutex_init(&pc->mutex, NULL);
}

void Inc(Counter* pc)
{
    pthread_mutex_lock(&pc->mutex);
    pc->count++;
    pthread_mutex_unlock(&pc->mutex);
}

void Dec(Counter* pc)
{
    pthread_mutex_lock(&pc->mutex);
    pc->count--;
    if (pc->count == 0)
    {
        pthread_mutex_unlock(&pc->mutex);
        pthread_mutex_destroy(&pc->mutex);
        free(pc);
    }
    else
    {
        pthread_mutex_unlock(&pc->mutex);
    }
}

关于死锁

如果一个线程试图对同一个互斥量加两次锁则会造成死锁。当然还有其他不明显的方式可能导致死锁,考虑以下的情况,线程A占有第一个互斥量,线程B占有第二个互斥量,线程A试图去占有第二个互斥量而出于阻塞,线程B试图去占有第一个互斥量时也处于阻塞,这样子一来,A在等待B释放锁,B也在等待A释放锁,相互阻塞,结果是谁也释放不了锁,造成死锁。

这里写图片描述

这里写图片描述

死锁一般要满足四个条件:

  1. 互斥
  2. 不可抢占
  3. 占有并等待
  4. 循环等待

上述解除死锁的方法实际上就是破坏这几个其中的一个,比如用trylock函数如果不能获得锁就释放锁,这就是破坏第三个条件,而按照锁的先后次序去得到锁则是破坏了第四个条件。

具体可参见死锁,银行家算法

2.条件变量

条件变量是线程可用的另一种同步机制,条件变量和互斥量一起使用,允许线程以无竞争的方式等待特定条件的发生。

这里写图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值