多线程(4)什么是锁?锁机制,死锁等说明
1. 什么是锁?
实现了对临界资源的互斥访问
2. 锁的种类
锁的种类:互斥锁,读写锁,自旋锁,递归锁
2.1.互斥锁
以排他的方式防止数据被同时修改
2.2.读写锁
- 允许多个线程同时读操作,但对写操作是互斥的。
- 如果有其他线程读操作,则允许其他线程进行读操作,但不运行写操作。
- 如果有线程进行写数据,则其他线程都不运行读和写操作;
- 适用场景: 解决频繁读取,偶尔写入的问题
2.3.自旋锁
自旋锁不会引起调用者睡眠,而是一直循环看是否该持有锁是否已经释放了锁。
2.3.1 自旋锁和互斥锁区别
-
自旋锁和互斥锁相同点
自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。
无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者。 -
自旋锁和互斥锁区别:
两者在调度机制上略有不同。
对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。
但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,“自旋”一词就是因此而得名。
2.4.递归锁
开始引用锁的时候,就产生它,当在锁没有解开的时候,还要继续用锁,就简单的加一,解开一把就减一,当计数为零时,就把锁销毁掉。
3 死锁
定义:
两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。
此时称系统处于死锁状态或系统产生了死锁,
这些永远在互相等待的进程称为死锁进程。
3.1 死锁常见代码形式
3.1.1 死锁情况1:
加锁 A B 顺序也会导致死锁
线程1
lock A
LOCK B
...
UNLOCK B
UNLOCK A
线程2
lock B
LOCK A
...
UNLOCK B
UNLOCK A
3.1.2 死锁情况2:
线程1
func1
lock A
LOCK B
...
UNLOCK B
UNLOCK A
线程2
lock A
func1
LOCK B
...
UNLOCK B
UNLOCK A