互斥锁
(1、当多个线程几乎同时修改某一个共享数据的时候,需要进行同步控制
(2、线程同步能够保证多个线程安全访问竞争资源,最简单的同步机制是引入互斥锁
(3、互斥锁为资源引入一个状态: 锁定/非锁定
(4、某个线程要更改共享数据时,先将其锁定,此时资源的状态为‘锁定’,其他线程不能更改;直到
该线程释放资源,将资源的状态变成‘非锁定’,其他的线程才能再次锁定该资源。互斥锁保证了每次只有一个线程进入写入操作,从而保证了多线程情况下的正确性
操作:
threading.Lock()
**
**threading模块中定义了Lock类,可以方便的处理锁定:- #创建锁**
**mutex=threading.Lock()
- #锁定**
**mutex.acquire()
- #释放**
**mutex.release()
注意:
- 如果这个锁之前是没有上锁的,那么acquire不会堵塞
- 如果再调用acquire对这个锁上锁之前,他已经被其他线程上了锁,那么此时acquire会堵塞,直到这个锁被解锁为止
- 这个锁是当多个线程几乎同时修改某一个共享数据的时候,需要进行的同步控制**
**是修改某一个共享数据!!!!!!!!!!!!!!
示例代码:
import threading,time
def work1():
global num
c=0
mutex.acquire()
for x in range(4):
num+=1
c+=1
print('%d次的值为%d'%(x,num))
if c==2:
mutex.release()
time.sleep(2)
mutex.acquire()
mutex.release()
def work2():
global num
mutex.acquire()
num=num+1
print('经过work2后的值为:%d'%num)
mutex.release()
num=1
mutex=threading.Lock()
a=threading.Thread(target=work1)
s=threading.Thread(target=work2)
a.start()
s.start()
s.join()
a.join()
num=num+2
print(num)
结果是:
0次的值为2
1次的值为3
经过work2后的值为:4
2次的值为5
3次的值为6
8
锁的优缺点:
-
锁的优点:
- 确保了某段关键代码只能由一个线程从头到尾完整地执行
-
锁的缺点:
- 阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下降了
- 由于可以存在多个锁,不同的线程持有不同的锁,并试图获取对方持有的锁时,可能会造成死锁
死锁:
在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。**
**尽管死锁很少发生,但一旦发生就会造成应用的停止响应
避免死锁
1、程序设计时要尽量避免(银行家算法)**
**2、添加超时时间等待