摘要:信號(hào)量使用前執(zhí)行后發(fā)現(xiàn)不斷在輸出使用后通過執(zhí)行上面的代碼,我們發(fā)現(xiàn)一次只能輸出三個(gè)數(shù)字,控制訪問并發(fā)量事件等待后,才能往下執(zhí)行定義五個(gè)線程重置,使得起到阻塞作用啟動(dòng)所有線程等待喚醒所有線程等待喚醒所有線程
本文講python中的四種鎖
Lock互斥鎖
使用前
num = 0 def a(): global num for _ in range(10000000): num += 1 def b(): global num for _ in range(10000000): num += 1 if __name__ == "__main__": t1=Thread(target=a) t1.start() t2=Thread(target=b) t2.start() t1.join() t2.join() print(num) #基本永遠(yuǎn)會(huì)小于20000000
使用后
num = 0 def a(lock): global num for _ in range(1000000): with lock: num += 1 def b(lock): global num for _ in range(1000000): with lock: num += 1 if __name__ == "__main__": lock = threading.Lock() t1=Thread(target=a, args=(lock,)) t1.start() t2=Thread(target=b, args=(lock,)) t2.start() t1.join() t2.join() print(num) #永遠(yuǎn)會(huì)輸出20000000
RLock重用鎖
#在之前的代碼中永遠(yuǎn)不可能出現(xiàn)鎖在沒釋放之前重新獲得鎖,但rlock可以做到,但只能發(fā)生在一個(gè)線程中,如: num = 0 def a(lock): with lock: print("我是A") b(lock) def b(lock): with lock: print("我是b") if __name__ == "__main__": lock = threading.Lock() t1 = Thread(target=a, args=(lock,)) t1.start() #會(huì)發(fā)生死鎖,因?yàn)樵诘谝淮芜€沒釋放鎖后,b就準(zhǔn)備上鎖,并阻止a釋放鎖
使用后
if __name__ == "__main__": lock = threading.RLock() #只需要改變鎖為RLock程序馬上恢復(fù) t1 = Thread(target=a, args=(lock,)) t1.start()
Condition同步鎖
#這個(gè)程序我們模擬甲乙對(duì)話 Jlist = ["在嗎", "干啥呢", "去玩兒不", "好吧"] Ylist = ["在呀", "玩兒手機(jī)", "不去"] def J(list): for i in list: print(i) time.sleep(0.1) def Y(list): for i in list: print(i) time.sleep(0.1) if __name__ == "__main__": t1 = Thread(target=J, args=(Jlist,)) t1.start() t1.join() t2 = Thread(target=Y, args=(Ylist,)) t2.start() t2.join() #上面的程序輸出后發(fā)現(xiàn)效果就是咱們想要的,但是我們每次輸出后都要等待0.1秒,也無法正好確定可以拿到時(shí)間片的最短時(shí)間值,并且不能保證每次正好都是另一個(gè)線程執(zhí)行。因此,我們用以下方式,完美解決這些問題。
使用后
Jlist = ["在嗎", "干啥呢", "去玩兒不", "好吧"] Ylist = ["在呀", "玩兒手機(jī)", "不去","哦"] def J(cond, list): for i in list: with cond: print(i) cond.notify() cond.wait() def Y(cond, list): for i in list: with cond: cond.wait() print(i) cond.notify() if __name__ == "__main__": cond = threading.Condition() t1 = Thread(target=J, args=(cond, Jlist)) t2 = Thread(target=Y, args=(cond, Ylist)) t2.start() t1.start() #一定保證t1啟動(dòng)在t2之后,因?yàn)閚otify發(fā)送的信號(hào)要被t2接受到,如果t1先啟動(dòng),會(huì)發(fā)生阻塞。
Seamplore信號(hào)量
使用前
class B(threading.Thread): def __init__(self, name): super().__init__() self.name = name def run(self): time.sleep(1) print(self.name) class A(threading.Thread): def __init__(self): super().__init__() def run(self): for i in range(100): b = B(i) b.start() if __name__ == "__main__": a = A() a.start() #執(zhí)行后發(fā)現(xiàn)不斷在輸出
使用后
class B(threading.Thread): def __init__(self, name, sem): super().__init__() self.name = name self.sem = sem def run(self): time.sleep(1) print(self.name) sem.release() class A(threading.Thread): def __init__(self, sem): super().__init__() self.sem = sem def run(self): for i in range(100): self.sem.acquire() b = B(i, self.sem) b.start() if __name__ == "__main__": sem = threading.Semaphore(value=3) a = A(sem) a.start() #通過執(zhí)行上面的代碼,我們發(fā)現(xiàn)一次只能輸出三個(gè)數(shù)字,sem控制訪問并發(fā)量
Event事件
import time import threading class MyThread(threading.Thread): def __init__(self, name, event): super().__init__() self.name = name self.event = event def run(self): print("Thread: {} start at {}".format(self.name, time.ctime(time.time()))) # 等待event.set()后,才能往下執(zhí)行 self.event.wait() print("Thread: {} finish at {}".format(self.name, time.ctime(time.time()))) event = threading.Event() # 定義五個(gè)線程 threads = [MyThread(str(i), event) for i in range(1,5)] # 重置event,使得event.wait()起到阻塞作用 event.clear() # 啟動(dòng)所有線程 [t.start() for t in threads] print("等待5s...") time.sleep(5) print("喚醒所有線程...") event.set() # output: """ Thread: 1 start at Sun May 13 20:38:08 2018 Thread: 2 start at Sun May 13 20:38:08 2018 Thread: 3 start at Sun May 13 20:38:08 2018 Thread: 4 start at Sun May 13 20:38:08 2018 等待5s... 喚醒所有線程... Thread: 1 finish at Sun May 13 20:38:13 2018 Thread: 4 finish at Sun May 13 20:38:13 2018 Thread: 2 finish at Sun May 13 20:38:13 2018 Thread: 3 finish at Sun May 13 20:38:13 2018 """
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/42783.html
摘要:但現(xiàn)在線程沒有優(yōu)先級(jí),沒有線程組,不能被銷毀停止暫停開始和打斷。守護(hù)線程也會(huì)結(jié)束,并強(qiáng)行終止整個(gè)程序。在中,他是目前可用的最底層的同步原語,由模塊提供。當(dāng)處于狀態(tài)時(shí),方法可以將狀態(tài)變?yōu)椋⒘⒓捶祷亍7駝t會(huì)拋出錯(cuò)誤。對(duì)象實(shí)現(xiàn)某些服務(wù)的共進(jìn)退。 Python的threading模塊松散地基于Java的threading模塊。但現(xiàn)在線程沒有優(yōu)先級(jí),沒有線程組,不能被銷毀、停止、暫停、開始和打...
摘要:的類行為是的類行為的子集,目前尚不支持優(yōu)先級(jí)線程組,線程無法銷毀停止暫停恢復(fù)或中斷。表示繼承創(chuàng)建該線程的當(dāng)前線程的屬性。重入鎖,同步原語的一種,可由同一線程多次獲取已持有的鎖。 threading在低級(jí)的_thread模塊上構(gòu)建了更高級(jí)的線程接口。 threading模塊基于Java線程模型設(shè)計(jì)。不過Java中鎖和條件變量是每個(gè)對(duì)象的基本行為,在python中卻是單獨(dú)的對(duì)象。pytho...
摘要:可以將它們認(rèn)為是在一個(gè)主進(jìn)程或主線程中并行運(yùn)行的一些迷你進(jìn)程。因此與進(jìn)程相比,線程之間的信息共享和通信更加容易。當(dāng)上鎖的線程執(zhí)行完畢進(jìn)行解鎖,堵塞的線程就爭(zhēng)奪到上鎖權(quán)而進(jìn)行代碼塊的運(yùn)行。 threading模塊 線程簡(jiǎn)述 線程(輕量級(jí)進(jìn)程)與進(jìn)程類似,不過它們是在同一個(gè)進(jìn)程下執(zhí)行的,并共享相同的上下文。可以將它們認(rèn)為是在一個(gè)主進(jìn)程或主線程中并行運(yùn)行的一些迷你進(jìn)程。 線程包括開始、執(zhí)行順...
摘要:如果某線程并未使用很多操作,它會(huì)在自己的時(shí)間片內(nèi)一直占用處理器和。在中使用線程在和等大多數(shù)類系統(tǒng)上運(yùn)行時(shí),支持多線程編程。守護(hù)線程另一個(gè)避免使用模塊的原因是,它不支持守護(hù)線程。 這一篇是Python并發(fā)的第四篇,主要介紹進(jìn)程和線程的定義,Python線程和全局解釋器鎖以及Python如何使用thread模塊處理并發(fā) 引言&動(dòng)機(jī) 考慮一下這個(gè)場(chǎng)景,我們有10000條數(shù)據(jù)需要處理,處理每條...
摘要:操作系統(tǒng)實(shí)戰(zhàn)臨界資源保護(hù)臨界資源進(jìn)行通信線程間同步互斥量和讀寫鎖自旋鎖條件變量進(jìn)程間同步共享內(nèi)存域套接字重要概念用戶態(tài)與內(nèi)核態(tài)上下文切換協(xié)程線程同步之互斥量互斥量鎖可以保證多線程的指令按順序執(zhí)行,避免兩個(gè)線程的指令交叉執(zhí)行即原子性原子性是指 操作系統(tǒng)實(shí)戰(zhàn) 臨界資源 保護(hù)臨界資源/進(jìn)行通信 線程間同步 互斥量和 讀寫鎖 自旋鎖 條件變量 進(jìn)程間同步 共享內(nèi)存 域套接字 重要概念 用...
閱讀 2250·2023-04-26 01:50
閱讀 712·2021-09-22 15:20
閱讀 2590·2019-08-30 15:53
閱讀 1592·2019-08-30 12:49
閱讀 1712·2019-08-26 14:05
閱讀 2710·2019-08-26 11:42
閱讀 2306·2019-08-26 10:40
閱讀 2597·2019-08-26 10:38