当前位置: 首页 > news >正文

Linux中的线程互斥

一、背景

多个线程能看到的资源叫共享资源,我们需要对资源进行保护,就要线程互斥。

1、背景一

CPU的运算分为逻辑运算和算术运算。以逻辑运算为例子:tickets = 1000; tickets > 0

2、背景二

在CPU中寄存器只有一套,但是寄存器中数据有多套。

数据是线程私有的,虽然放在了一个公共区域,但是线程的切换会带走自己的数据,回来的时候在恢复数据,所以数据仍然私有。

虽然数据是私有的,但是由于线程的切换会导致线程执行代码的过程是碎片的,对于一些全局的变量如果由于线程的切换执行代码导致被多个线程访问就会带来许多非法操作,这就是开头说的我们需要对共享资源进行保护,就要线程互斥。

二、线程互斥的实现:锁

1、基本知识

首先我们清楚程序员访问资源的方式就是代码,线程去执行代码就是访问资源。

所以访问不是共享资源的代码就是非临界区,访问共享资源的代码就是临界区。

对临界资源的保护就是对临界区代码的保护。锁就是用来保护临界区的。

2、锁的接口

(1)创建锁

int pthread_mutex_init(pthread_mutex_t* restrict mutex, const pthread_mutex_t* restrict attr)

用来定义局部锁,在栈上。(要调用函数销毁锁)

pthread_mutex_t:锁的数据类型

attr:锁的属性

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER

用来定义全局锁(不用手动销毁)

(2)销毁锁

int pthread_mutex_destroy(pthread_mutex_t* mutex)

(3)加锁

int pthread_mutex_lock(pthread_mutex_t* mutex)

(4)解锁

int pthread_mutex_unlock(pthread_mutex_t* mutex)

3、代码案例

4、锁实现互斥的原理

未来会有很多线程访问代码,涉及临界区资源访问的代码只能同时只有一个线程访问,当多个线程竞争同一把锁时只有加锁成功的线程才能继续运行下面的代码也就是临界区,这样就保护了临界区。

注意

(1)加锁范围粒度要小。

(2)所有线程申请锁的前提是所有线程能看到同一把锁,锁本身就是共享资源。加锁的过程就必须是原子的。

(3)如果线程申请锁失败线程就会被阻塞。

(4)锁申请成功将执行临界区代码。

(5)申请锁成功执行临界区代码时可能会被CPU切走,但其他线程依然无法进入临界区。

申请锁成功本质就是 pthread_mutex_lock() 返回值,线程继续向后运行。

申请锁失败本质就是 pthread_mutex_lock() 不返回,线程阻塞。

不返回:申请锁的条件不成立,函数内部把线程状态改变使其阻塞。

锁被释放本质是 pthread_mutex_unlock() 在 pthread_mutex_lock() 内部重新唤醒,重新申请锁。

5、认识锁

我们用汇编伪代码解释锁

加锁过程:

(1)movb $0, &al           把寄存器al中的值置0

(2)xchgb %al, mutex    交换内存中锁的值和寄存器al的值

(3)如果交换来的值是1,就说明线程加锁成功,此时内存中锁的值是0,如果本线程不释放锁,下面线程交换来的都是0,实现只有一个线程访问临界区

(4)如果交换来的值是0,线程挂起等待

解锁过程:

(1)把内存中锁的值变成1,表示可以竞争锁了

(2)唤醒等待锁的线程竞争

三、补充知识

1、CPU中寄存器只有一套,被线程共享,但寄存器里面的数据是执行流上下文,属于执行流的私有数据。

2、CPU在执行代码时,一定有对应的执行载体,线程或进程

3、数据在内存中,被所有线程共享。

4、总结上述三点,得出结论:把数据从内存移动到寄存器,本质就是把数据从共享变成私有。


http://www.mrgr.cn/news/3278.html

相关文章:

  • 利用netty实现websocket ;redis的订阅发布websocket相结合
  • Jakarta Servlet 到 SpringMVC
  • 达梦数据库的系统视图v$tablespace
  • pdf文件加密学习起,pdf 中图片如何提取文本
  • GStreamer 简明教程(四):Seek 以及获取文件时长
  • C++竞赛初阶L1-12-第五单元-while(27~28课)531: T456440 含 k 个 3 的数
  • 开源好用的堡垒机工具Jumpserver
  • 基于Springboot和BS架构的宠物健康咨询系统pf
  • 【无标题】
  • 自开发多功能Vue组件:可定义滚动速度[回到顶部/底部]图标组件的安装与使用!
  • 网络基础(一)
  • SOL项目开发代币DApp的基本要求、模式创建与海外宣发策略
  • 工业互联网与大数据实训室解决方案
  • 【网工学习】同VLAN不同网段能不能互通?
  • 【微服务】springboot 整合表达式计算引擎 Aviator 使用详解
  • H5 简约四色新科技风引导页源码
  • iPhone变身万能钥匙,iOS 18.1让你的手机解锁一切
  • Qt配置文件处理类(QSettings)
  • 【软件测试】单元测试20套练习题
  • 【前端面试】深入接口风格restful、graphQL