Python中Threading用法詳解
Python的threading模塊松散地基于Java的threading模塊。但現(xiàn)在線程沒有優(yōu)先級(jí),沒有線程組,不能被銷毀、停止、暫停、開始和打斷。 Java Thread類的靜態(tài)方法,被移植成了模塊方法。
main thread: 運(yùn)行python程序的線程
daemon thread 守護(hù)線程,如果守護(hù)線程之外的線程都結(jié)束了。守護(hù)線程也會(huì)結(jié)束,并強(qiáng)行終止整個(gè)程序。不要在守護(hù)進(jìn)程中進(jìn)行資源相關(guān)操作。會(huì)導(dǎo)致資源不能正確的釋放。在非守護(hù)進(jìn)程中使用Event。
Thread 類
(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
group: 為以后的ThreadGroup類預(yù)留 target: 被執(zhí)行的對(duì)象,由run()方法執(zhí)行 args: target對(duì)象使用的參數(shù) daemon: 是否為守護(hù)進(jìn)程
start()
每個(gè)thread 對(duì)象都只能被調(diào)用1次start()
run()
如果創(chuàng)建Thread的子類,重寫該方法。負(fù)責(zé)執(zhí)行target參數(shù)傳來的可執(zhí)行對(duì)象。
join()
阻塞線程直到結(jié)束。
GIL
在CPython中,由于GIL的存在,Python每次只能執(zhí)行一個(gè)線程。如果要充分利用多核機(jī)器的計(jì)算資源需要使用multiprocessing或者是concurrent.futures.ProcessPollExecutor。 但,但如果你想要很多I/O相關(guān)的并發(fā)操作,threding仍然是一個(gè)很好的選擇 。?因?yàn)橄到y(tǒng)自動(dòng)實(shí)現(xiàn)了線程的上下文切換。
from threading import Thread import requests url = 'http://www.baidu.com' urls = [url]*20 threads = [] for url in urls: t = Thread(target=requests.get, args=(url, )) t.start() threads.append(t) for t in threads: t.join()
鎖(Lock)對(duì)象
原始鎖(primitive lock),當(dāng)它鎖住的時(shí)候,它是一種不屬于任何一個(gè)線程的同步原語(synchronization primitive)。 在Python中,他是目前可用的最底層的同步原語,由_thread模塊提供。
一個(gè)原始鎖有兩個(gè)狀態(tài):locked 和unlocked。鎖創(chuàng)建時(shí),處于unlocked狀態(tài)。 鎖由兩個(gè)基本方法:acquire()和release()。
當(dāng)處于unlocked狀態(tài)時(shí),acquire(()方法可以將狀態(tài)變?yōu)閘ocked,并立即返回。當(dāng)處于locked狀態(tài)時(shí),acquire()會(huì)阻塞直至另一個(gè)線程調(diào)用了release()使改鎖解鎖,然后acquire()將鎖上鎖,并返回。
release()方法只能在鎖locked時(shí)別調(diào)用,并釋放鎖。否則會(huì)拋出RuntimeError錯(cuò)誤。
如果有多個(gè) acquire()在等待解鎖,則不確定哪一個(gè)哪一個(gè)會(huì)被觸發(fā)。
class threading.Lock
如果一個(gè)線程acquire了一個(gè)鎖,那么后續(xù)獲取它的線程都會(huì)被阻塞,直至鎖被釋放。任何線程都可以釋放鎖。
Lock是一個(gè)工廠函數(shù),返回當(dāng)前平臺(tái)下最高效的concrete Lock類的實(shí)例。
Lock支持上下文管理方法(context management protocol),也就是with 語句。在存在競(jìng)態(tài)條件(race condition)的時(shí)候,要使用鎖。比如多線程共同操作某個(gè)數(shù)據(jù)。
# 摘自python Cookbook import threading class SharedCounter: def __init__(self, init_value=0): self._value = init_value self._value_lock = threading.Lock() def incr(self, delta=1): # 在這里使用了with 語句,創(chuàng)建一個(gè)鎖,增加值,釋放鎖。 with self._value_lock: self._value += 1
RLock對(duì)象
可重入鎖(reentrant lock)。感覺是一個(gè)鎖中鎖,就是可以遞歸的鎖。等見到具體的應(yīng)用例子再寫。
Condition對(duì)象
condition變量總是與某種鎖相關(guān),鎖可以是傳過來的,也可以通過默認(rèn)設(shè)置創(chuàng)建。如果有多個(gè) condition對(duì)象需要共享一個(gè)鎖時(shí),傳遞一個(gè)鎖是非常有用的。鎖是condition對(duì)象的一部分,你不用刻意的跟蹤它。
Timer對(duì)象
Timer是Thread的子類,所以也要接受function參數(shù),也可以被start()。 它的run()函數(shù)被重寫為先event.wait(interval),再啟動(dòng)function。
Barrier對(duì)象
實(shí)現(xiàn)某些服務(wù)的共進(jìn)退。
threading.Barrier(parties, action=None, timeout=None)
設(shè)置n=parties個(gè)線程,當(dāng)n個(gè)barrier.wait()被調(diào)用后,所有這些調(diào)用的阻塞被同時(shí)解除,執(zhí)行action
感覺Barrier可以實(shí)現(xiàn)很多復(fù)雜的功能。
相關(guān)文章
python全棧要學(xué)什么 python全棧學(xué)習(xí)路線
在本文中小編給大家整理了關(guān)于python全棧要學(xué)什么以及python全棧學(xué)習(xí)路線的知識(shí)點(diǎn)內(nèi)容,需要的朋友們參考下。2019-06-06PyCharm2018 安裝及破解方法實(shí)現(xiàn)步驟
這篇文章主要介紹了PyCharm2018 安裝及破解方法實(shí)現(xiàn)步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-09-09python獲取文件版本信息、公司名和產(chǎn)品名的方法
這篇文章主要介紹了python獲取文件版本信息、公司名和產(chǎn)品名的方法,是Python程序設(shè)計(jì)中非常實(shí)用的技巧,需要的朋友可以參考下2014-10-10淺析Python如何監(jiān)聽和響應(yīng)鍵盤按鍵
在許多編程場(chǎng)景中,接收并響應(yīng)用戶輸入是至關(guān)重要的,本文主要為大家詳細(xì)介紹如何使用Python來監(jiān)聽和響應(yīng)鍵盤按鍵,有需要的小伙伴可以參考下2024-03-03Python OpenCV實(shí)現(xiàn)圖像模板匹配詳解
提供一個(gè)模板圖像,一個(gè)目標(biāo)圖像,且滿足模板圖像是目標(biāo)圖像的一部分,從目標(biāo)圖像中尋找特定的模板圖像的過程,即為模板匹配。本文將詳細(xì)講解如何利用Python OpenCV實(shí)現(xiàn)圖像模板匹配,需要的可以參考一下2022-04-04