常用用法
t.is_alive()
Python中線(xiàn)程會(huì)在一個(gè)單獨(dú)的系統(tǒng)級(jí)別線(xiàn)程中執(zhí)行(比如一個(gè)POSIX線(xiàn)程或者一個(gè)Windows線(xiàn)程)
這些線(xiàn)程將由操作系統(tǒng)來(lái)全權(quán)管理。線(xiàn)程一旦啟動(dòng),將獨(dú)立執(zhí)行直到目標(biāo)函數(shù)返回。可以通過(guò)查詢(xún)
一個(gè)線(xiàn)程對(duì)象的狀態(tài),看它是否還在執(zhí)行t.is_alive()
t.join()
可以把一個(gè)線(xiàn)程加入到當(dāng)前線(xiàn)程,并等待它終止
Python解釋器在所有線(xiàn)程都終止后才繼續(xù)執(zhí)行代碼剩余的部分
daemon
對(duì)于需要長(zhǎng)時(shí)間運(yùn)行的線(xiàn)程或者需要一直運(yùn)行的后臺(tái)任務(wù),可以用后臺(tái)線(xiàn)程(也稱(chēng)為守護(hù)線(xiàn)程)
例:
t=Thread(target=func,args(1,),daemon=True)
t.start()
后臺(tái)線(xiàn)程無(wú)法等待,這些線(xiàn)程會(huì)在主線(xiàn)程終止時(shí)自動(dòng)銷(xiāo)毀
小結(jié):
后臺(tái)線(xiàn)程無(wú)法等待,不過(guò),這些線(xiàn)程會(huì)在主線(xiàn)程終止時(shí)自動(dòng)銷(xiāo)毀。你無(wú)法結(jié)束一個(gè)線(xiàn)程,無(wú)法給它發(fā)送信
號(hào),無(wú)法調(diào)整它的調(diào)度,也無(wú)法執(zhí)行其他高級(jí)操作。如果需要這些特性,你需要自己添加。比如說(shuō),
如果你需要終止線(xiàn)程,那么這個(gè)線(xiàn)程必須通過(guò)編程在某個(gè)特定點(diǎn)輪詢(xún)來(lái)退出
如果線(xiàn)程執(zhí)行一些像I/O這樣的阻塞操作,那么通過(guò)輪詢(xún)來(lái)終止線(xiàn)程將使得線(xiàn)程之間的協(xié)調(diào)變得非常棘手。
比如,如果一個(gè)線(xiàn)程一直阻塞在一個(gè)I/O操作上,它就永遠(yuǎn)無(wú)法返回,也就無(wú)法檢查自己是否已經(jīng)被結(jié)束了。
要正確處理這些問(wèn)題,需要利用超時(shí)循環(huán)來(lái)小心操作線(xiàn)程。
線(xiàn)程間通信
queue
一個(gè)線(xiàn)程向另外一個(gè)線(xiàn)程發(fā)送數(shù)據(jù)最安全的方式應(yīng)該就是queue庫(kù)中的隊(duì)列
先看一下使用例子,這里是一個(gè)簡(jiǎn)單的生產(chǎn)者和消費(fèi)者模型:
from queue import Queuefrom threading import Threadimport randomimport time_sentinel = object()def producer(out_q): n = 10 while n: time.sleep(1) data = random.randint(0, 10) out_q.put(data) print("生產(chǎn)者生產(chǎn)了數(shù)據(jù){0}".format(data)) n -= 1 out_q.put(_sentinel)def consumer(in_q): while True: data = in_q.get() print("消費(fèi)者消費(fèi)了{(lán)0}".format(data)) if data is _sentinel: in_q.put(_sentinel) breakq = Queue()t1 = Thread(target=consumer, args=(q,))t2 = Thread(target=producer, args=(q,))t1.start()t2.start()上述代碼中設(shè)置了一個(gè)特殊值_sentinel用于當(dāng)獲取到這個(gè)值的時(shí)候終止執(zhí)行
關(guān)于queue的功能有個(gè)需要注意的地方:
Queue對(duì)象雖然已經(jīng)包含了必要的鎖,主要有q.put和q.get
而q.size(),q.full(),q.empty()等方法不是線(xiàn)程安全的
使用隊(duì)列進(jìn)行線(xiàn)程通信是一個(gè)單向、不確定的過(guò)程。通常情況下,是沒(méi)有辦法知道接收數(shù)據(jù)的線(xiàn)程是什么時(shí)候接收到的數(shù)據(jù)并開(kāi)始工作的。但是隊(duì)列提供了一些基本的特性:q.task_done()和q.join()
如果一個(gè)線(xiàn)程需要在另外一個(gè)線(xiàn)程處理完特定的數(shù)據(jù)任務(wù)后立即得到通知,可以把要發(fā)送的數(shù)據(jù)和一個(gè)Event放到一起使用
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注