线程安全预防与总结

多个线程同时操作临界资源而不会出现数据二义性就是线程安全
临界资源:多线程执行流共享的资源就叫做临界资源
临界区:每个线程内部,访问临界自娱的代码,就叫做临界区
互斥:任何时刻,互斥保证有且只有一个执行流进入临界区,访问临界资源,通常对临界资源起保护作用
原子性:不会被任何调度机制打断的操作,该操作只有两态,要么完成,要么未完成
互斥量:
大部分情况,线程使用的数据都是局部变量,变量的地址空间在线程栈空间内,这种情况,变量归属单个线程,其他线程无法获得这种变量
但有时候,很多变量都需要在线程间共享,这样的变量称为共享变量,可以通过数据的共享,完成线程之间的交互
多个线程并发操作共享变量会带来线程安全问题
操作不是原子操作如何解决:
代码必须要有互斥行为:当代码进入临界区执行时,不允许其他线程进入该临界区。
如果多个线程同时要求执行临界区的代码,并且临界区没有线程在执行,那么只能允许一个线程进入该临界区。
如果线程不在临界区中执行,那么线程不能阻塞其他线程进入临界区
解决问题的方法加锁+条件变量实现同步和互斥
同步与互斥;
同步:临界资源的合理访问
互斥:临界资源同一时间唯一访问
互斥锁:
一个0/1的计数器:1表示可以加锁,加锁就是计数-1,操作完成后要解锁,解锁就是计数+1;0表示不能加锁,不能加加锁则等待
怎么保证自己是原子性操作
通过一步完成的
操作原子性操作不可被分割来保证互斥量修改的原子性(通过交换性的一步原子操作**)
互斥锁操作步骤:
1>定义互斥锁变量pthread_mutex_t
2>初始化互斥锁pthread_mutex_init
3>加锁解锁pthread_mutex_lock/pthread_mutex_lock
4>销毁互斥锁pthread_mutex_destroy
加锁在临界资源使用之前解锁临界资源都使用完后
死锁:死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态–>因为对一些无法加锁的锁行为进行加锁导致程序卡死
死锁产生的四射必要条件:
1>互斥条件:我操作时候别人不能操作–>一个资源只能被一个执行流使用
2>不可剥夺条件:我的锁,别人不能解
3>请求与保持条件:拿了第一个去请求第二个但是第二个获取不到,也不释放第一个
4>拿着手里的请求其他的,其他的请求不到手里的也不放
5>环路等待条件:若干执行流之间形成一种头尾相接的循环等待资源的关系,产生场景:加锁解锁顺序不同
死锁的预防:破坏必要条件
死锁的避免:银行家算法,死锁检测算法
同步的实现:–>临界资源访问的合理性–>生产出来才能使用–>等待+唤醒
没有资源则(死)等待,生产资源后则唤醒等待
条件变量
1>定义条件变量 pthread_cond_t
2>初始化条件变量 pthread_cond_init
3>等待/唤醒 pthread_cond_wait/
4>销毁条件变量
Pthread_cond_wait:集合了解锁,休眠,加锁的原子操作
因为加锁是非阻塞,所以条件判断应该是循环的
不同角色的线程应该等待在不同那个的条件变量上,防止错误唤醒导致卡死
eg:多个卖面的和多个吃面的—吃面应该唤醒卖面的,但是实际情况下唤醒的不一定是卖面的,因此会出现问题,所以所以需要分开等待分开唤醒(等待在不同的条件变量,唤醒不同条件变量的线程
常见的线程安全情况:
每个线程对全局变量或者静态变量只有读取的权限,而没有写入的权限,一般来说这些线程是安全的
类或者接口对于线程来说都是原子操作
多个线程之间的切换不会导致该接口的执行结果存在二义性
常见的不可重入情况:
(1)调用了malloc/free函数,因为malloc函数是用全局链表来管理堆的
(2)调用了标准I/O库函数,标准I/O库的很多实现都以不可重入的方式使用全局数据结构
(3)可重入函数体内使用了静态的数据结构
可重入:同一个函数被不同执行流调用,当前流没有完,就有其他流再次流入称为可重入,一个函数可重入情况下运行结果不会出现任何不同或者问题则称为可重入函数
可重入/不可重入:多个执行流中是否可以同时进入函数运行而不会出现问题
常见的可重入情况
不使用全局变量或静态变量
不使用用malloc或者new开辟出的空间
不调用不可重入函数
不返回静态或全局数据,所有数据都有函数的调用者提供
使用本地数据,或者通过制作全局数的本地拷贝来保护全局数据
可重入与线程安全联系
函数可重入/重入线程安全
函数不可重入不能由多个线程使用可能引发线程安全问题
如果一个函数有全局变量那么这个函数既不是线程安全也不是可重入的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值