linux 之线程基础 (三)、多线程编程的同步和互斥

linux 之线程基础 (三) 多线程编程的同步和互斥

  • 线程机制的优点:线程间很容易进行通信,通过全局变量实现数据共享和交换。
  • 线程机制缺点:多个线程同时访问共享对象时需要引入同步和互斥机制。

1. 同步与互斥的基本概念

1.1 同步

在多任务的操作系统环境下,多个进程/线程会同时运行。多个任务可能为了完成同一个目标会相互协作,按一定规则有序运行,这样就形成了任务之间的同步关系

同步概念:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。

1.2 互斥

同样,在不同任务之间为了争夺有限的资源(硬件或者是软件资源)会进入竞争状态,这就是任务之间的互斥关系

互斥:是指同时只允许一个访问者对临界资源进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。

1.3 临界资源

任务之间出现互斥和同步关系存在的根源在于临界资源。临界资源是指同一时间只能被一段指令序列所占用的资源就是所谓的临界资源。 stdout 就是临界资源。
临界资源举例子:

  • stdin
  • stdout
  • 打印机

上述资源,同一个时刻只能被一个线程占用,否则会造成打印紊乱。这类资源如果不被看成临界资源加以保护,那么很有可能因为访问冲突造成数据错乱的问题。
线程间机制,多线程共享同一个进程的地址空间

1.4 临界区

程序内访问临界资源的代码序列被称为临界区。

2. 实现同步和互斥的方式

2.1 实现同步

我们可以通过信号量的机制,来实现线程的同步,以达到控制线程执行顺序的目的。

2.2 实现互斥

由于同步的基础是在互斥上的,因此,信号量的机制也可以实现互斥。但是,实现互斥还有一种方式,就是互斥锁的方式

  • 通过信号量 实现互斥
  • 通过互斥锁 实现互斥

3. 使用互斥锁实现线程间的互斥

3.1 互斥锁简介

我们对线程的互斥主要介绍NPTL库自带的 pthread_mutex_t,该互斥锁有一下特点:

  • 引入互斥(mutual exclusion)锁的目的是用来保证共享数据操作的完整性。
  • 互斥锁主要用来保护临界资源。
  • 每个临界资源都由一个互斥锁来保护,任何时刻最多只能有一个线程能访问该资源。
  • 线程必须先获得互斥锁才能访问临界资源,访问完临界资源后释放该锁。如果无法获得锁,线程会阻塞直到获得锁为止
3.2 互斥所的两种状态

互斥锁只有两种状态:上锁和解锁,可以将互斥锁看成某种意义上的全局变量。在同一时刻只能有一个线程拥有互斥锁,拥有互斥锁的线程才能能够对共享资源进行操作。若线程对一个已经被上锁的互斥锁加锁时,该线程就会睡眠,直到其他线程释放互斥锁位置。

注意:
上锁和解锁的操作是原子的。所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会有任何 context switch (切换到另一个线程)。互斥只能保证同一时刻只有一个人获得锁,但是不保证线程获得锁的顺序。

4. 互斥锁API

4.1 初始化互斥锁

需要首先定义一个全局变量的 互斥锁变量,互斥锁变量的类型为pthread_mutex_t。

4.1.1 动态初始化互斥锁
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t 
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值