48_并发编程-线程-资源共享/锁
生活随笔
收集整理的這篇文章主要介紹了
48_并发编程-线程-资源共享/锁
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
一、數(shù)據(jù)共享 多個線程內(nèi)部有自己的數(shù)據(jù)棧,數(shù)據(jù)不共享;全局變量在多個線程之間是共享的。 1 # 線程數(shù)據(jù)共享不安全加鎖
2
3 import time
4 from threading import Thread, Lock
5
6
7 num = 100
8
9 def func(t_lock):
10 global num
11 t_lock.acquire()
12 mid = num
13 mid -= 1
14 time.sleep(0.01) # 設(shè)置一個時(shí)間,模擬數(shù)據(jù)修改時(shí),先從內(nèi)存中拿出作修改,在把結(jié)果放回去的時(shí)間差
15 num = mid
16 t_lock.release()
17
18 if __name__ == '__main__':
19
20 t_lock = Lock()
21
22 t_lst = []
23 for i in range(10):
24 t_thread = Thread(target=func, args=(t_lock,))
25 t_lst.append(t_thread)
26 t_thread.start()
27 [t_obj.join() for t_obj in t_lst] #必須加join,因?yàn)橹骶€程和子線程不一定誰快,一般都是主線程快一些,所有我們要等子線程執(zhí)行完畢才能看出效果
28
29 print('主線程結(jié)束!', num) # 結(jié)果為90 數(shù)據(jù)共享實(shí)例 二、同步鎖(互斥鎖) -?產(chǎn)生死鎖 進(jìn)程也有死鎖與遞歸鎖,在進(jìn)程那里忘記說了,放到這里一切說了額,進(jìn)程的死鎖和線程的是一樣的,而且一般情況下進(jìn)程之間是數(shù)據(jù)不共享的,不需要加鎖,由于線程是對全局的數(shù)據(jù)共享的,所以對于全局的數(shù)據(jù)進(jìn)行操作的時(shí)候,要加鎖。 死鎖: 是指兩個或兩個以上的進(jìn)程或線程在執(zhí)行過程中,因爭奪資源而造成的一種互相等待的現(xiàn)象,若無外力作用,它們都將無法推進(jìn)下去。此時(shí)稱系統(tǒng)處于死鎖狀態(tài)或系統(tǒng)產(chǎn)生了死鎖,這些永遠(yuǎn)在互相等待的進(jìn)程稱為死鎖進(jìn)程,如下就是死鎖 1 from threading import Thread,Lock
2 import time
3
4 class MyThread(Thread):
5 def run(self):
6 self.func1()
7 self.func2()
8 def func1(self):
9 mutexA.acquire()
10 print('\033[41m%s 拿到A鎖>>>\033[0m' %self.name)
11 mutexB.acquire()
12 print('\033[42m%s 拿到B鎖>>>\033[0m' %self.name)
13 mutexB.release()
14 mutexA.release()
15
16 def func2(self):
17 mutexB.acquire()
18 print('\033[43m%s 拿到B鎖???\033[0m' %self.name)
19 time.sleep(2)
20 #分析:當(dāng)線程1執(zhí)行完func1,然后執(zhí)行到這里的時(shí)候,拿到了B鎖,線程2執(zhí)行func1的時(shí)候拿到了A鎖,那么線程2還要繼續(xù)執(zhí)行func1里面的代碼,再去拿B鎖的時(shí)候,發(fā)現(xiàn)B鎖被人拿了,那么就一直等著別人把B鎖釋放,那么就一直等著,等到線程1的sleep時(shí)間用完之后,線程1繼續(xù)執(zhí)行func2,需要拿A鎖了,但是A鎖被線程2拿著呢,還沒有釋放,因?yàn)樗诘戎鳥鎖被釋放,那么這倆人就尷尬了,你拿著我的老A,我拿著你的B,這就尷尬了,倆人就停在了原地
21
22 mutexA.acquire()
23 print('\033[44m%s 拿到A鎖???\033[0m' %self.name)
24 mutexA.release()
25 mutexB.release()
26
27 if __name__ == '__main__':
28
29 mutexA=Lock() # 同步鎖必須這樣創(chuàng)建
30 mutexB=Lock()
31 for i in range(10):
32 t=MyThread()
33 t.start()
34
35 '''
36 Thread-1 拿到A鎖>>>
37 Thread-1 拿到B鎖>>>
38 Thread-1 拿到B鎖???
39 Thread-2 拿到A鎖>>>
40 然后就卡住,死鎖了
41 ''' 死鎖現(xiàn)象
三、解決死鎖方案 -?遞歸鎖 解決方法,遞歸鎖,在Python中為了支持在同一線程中多次請求同一資源,python提供了可重入鎖RLock。 這個RLock內(nèi)部維護(hù)著一個Lock和一個counter變量,counter記錄了acquire的次數(shù),從而使得資源可以被多次require。直到一個線程所有的acquire都被release,其他的線程才能獲得資源。上面的例子如果使用RLock代替Lock,則不會發(fā)生死鎖: 1 import time 2 from threading import Thread,RLock 3 4 5 class MyThread(Thread): 6 7 def __init__(self, lockA, lockB): 8 super().__init__() 9 self.lockA = lockA 10 self.lockB = lockB 11 def run(self): 12 self.func1() 13 self.func2() 14 15 def func1(self): 16 self.lockA.acquire() 17 print('我是func1') 18 self.lockB.acquire() 19 print('func1中有其他事') 20 self.lockB.release() 21 self.lockA.release() 22 23 def func2(self): 24 self.lockB.acquire() 25 print('我是func2') 26 time.sleep(0.5) 27 self.lockA.acquire() 28 print('func2中有什么事') 29 self.lockA.release() 30 self.lockB.release() 31 32 if __name__ == '__main__': 33 34 lockA = lockB = RLock() 35 36 t1 = MyThread(lockA, lockB) 37 t1.start() 38 t2 = MyThread(lockA, lockB) 39 t2.start() 40 print('嗯嗯,兩人不錯') 遞歸鎖
轉(zhuǎn)載于:https://www.cnblogs.com/hq82/p/9858375.html
總結(jié)
以上是生活随笔為你收集整理的48_并发编程-线程-资源共享/锁的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【SCOI2005】【BZOJ1087】
- 下一篇: [安卓基础] 008.Android中的