成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

python模塊之threading

nanchen2251 / 1988人閱讀

摘要:的類行為是的類行為的子集,目前尚不支持優(yōu)先級(jí)線程組,線程無法銷毀停止暫?;謴?fù)或中斷。表示繼承創(chuàng)建該線程的當(dāng)前線程的屬性。重入鎖,同步原語的一種,可由同一線程多次獲取已持有的鎖。

threading在低級(jí)的_thread模塊上構(gòu)建了更高級(jí)的線程接口。

threading模塊基于Java線程模型設(shè)計(jì)。不過Java中鎖和條件變量是每個(gè)對(duì)象的基本行為,在python中卻是多帶帶的對(duì)象。python的Thread類行為是Java的Thread類行為的子集,目前尚不支持優(yōu)先級(jí)、線程組,線程無法銷毀、停止、暫停、恢復(fù)或中斷。Java中Thread類的靜態(tài)方法在Python中映射為模塊級(jí)的函數(shù)。

模塊級(jí)函數(shù)

threading.active_count()
返回當(dāng)前活動(dòng)的Thread對(duì)象的數(shù)量,與enumerate()函數(shù)返回的列表元素個(gè)數(shù)相同

threading.current_thread()
返回當(dāng)前Thread對(duì)象,對(duì)應(yīng)調(diào)用者的控制線程(thread of control)。如果調(diào)用者的控制線程不是通過threading模塊創(chuàng)建,返回一個(gè)功能受限的啞線程對(duì)象(dummy thread object)

threading.get_ident()
返回一個(gè)非零整數(shù),代表當(dāng)前線程的"線程標(biāo)識(shí)符"。這個(gè)值意在作為魔術(shù)cookie使用,例如作為索引從特定于線程的字典對(duì)象獲取數(shù)據(jù)。當(dāng)一個(gè)線程退出,新的線程創(chuàng)建,線程標(biāo)識(shí)符可能被回收使用

threading.enumerate()
返回當(dāng)前活動(dòng)Thread對(duì)象的列表。該列表包含守護(hù)線程、current_thread()函數(shù)創(chuàng)建的啞線程,以及主線程,不包含已終止的線程和未啟動(dòng)的線程。

threading.main_thread()
返回主線程對(duì)象。通常來說,主線程就是啟動(dòng)python解釋器的線程。

threading.settrace(func)
為啟動(dòng)自threading模塊的所有線程設(shè)置一個(gè)trace函數(shù)。在每個(gè)線程的run()方法調(diào)用前,傳遞func參數(shù)給sys.settrace()

threading.setprofile(func)
為啟動(dòng)自threading模塊的所有線程設(shè)置一個(gè)profile函數(shù)。在每個(gè)線程的run()方法調(diào)用前,傳遞func參數(shù)給sys.setprofile()

threading.stack_size([size])
返回創(chuàng)建新線程使用的線程堆棧大小。

可選參數(shù)size指定后續(xù)創(chuàng)建的線程的堆棧大小,必須是0(表示使用平臺(tái)或配置的默認(rèn)值)或大于等于32768(32KiB)的正整數(shù)。如果未指定,默認(rèn)size為0.

如果不支持改動(dòng)線程堆棧大小,拋出RuntimeError異常。如果size不合法,拋出ValueError異常,堆棧大小保持不變。

32KiB是目前能保證解釋器堆棧空間充足的最小值。某些平臺(tái)可能對(duì)堆棧大小做了特殊的限制,比如要求最小堆棧大小在32KiB以上,或要求以系統(tǒng)內(nèi)存頁大小的倍數(shù)分配。

Windows系統(tǒng)及使用POSIX線程的系統(tǒng)可用

常量

threading.TIMEOUT_MAX
阻塞函數(shù)(Lock.acquire(), RLock.acquire(), Condition.wait()等)的timeout參數(shù)可接受的最大值。超出該值將拋出OverflowError異常。

Thread-Local Data

Thread-local數(shù)據(jù)的值是特定于線程的。管理Thread-local數(shù)據(jù),只需要?jiǎng)?chuàng)建local或其子類的實(shí)例并在該實(shí)例上存儲(chǔ)屬性:

mydata = threading.local()
mydata.x = 1

不同的線程,實(shí)例的值也會(huì)不同。

class threading.local

表示thread-local數(shù)據(jù)的類。

Thread

Thread類代表在多帶帶的控制線程中運(yùn)行的活動(dòng),有兩種方式指定:傳遞可調(diào)用對(duì)象到構(gòu)造器的target參數(shù),或重寫子類的run()方法。除了__int__()方法和run()方法,Thread子類不應(yīng)該重寫除此之外的其他方法。

創(chuàng)建的線程對(duì)象,必須使用start()方法啟動(dòng),start()在一個(gè)多帶帶的控制線程調(diào)用run()方法。這時(shí)該線程被認(rèn)為是"活動(dòng)的"。當(dāng)run()方法結(jié)束(正常執(zhí)行完成或拋出了未處理的異常)時(shí),線程對(duì)象不再是"活動(dòng)的"。is_alive()方法可用于檢查線程是否處于活動(dòng)狀態(tài)。

調(diào)用線程對(duì)象的join()方法將導(dǎo)致線程阻塞,直到調(diào)用join()方法的線程執(zhí)行結(jié)束。

線程擁有名字,可以傳遞給構(gòu)造器。通過name屬性讀取或修改。

主線程:對(duì)應(yīng)python程序的初始控制線程。主線程不是守護(hù)線程。

守護(hù)線程:當(dāng)沒有非守護(hù)線程處于活動(dòng)狀態(tài)時(shí),整個(gè)python程序?qū)⑼顺?。通過daemon屬性或構(gòu)造器參數(shù),可以標(biāo)記一個(gè)線程為守護(hù)線程。daemon屬性的初始值繼承自創(chuàng)建該線程的線程

啞線程:對(duì)應(yīng)"外部線程"alien thread,即在threading模塊之外(比如C代碼)啟動(dòng)的控制線程。啞線程具有有限的功能,總是認(rèn)為是活動(dòng)的和守護(hù)的,不能調(diào)用join()方法。它們永遠(yuǎn)不會(huì)被刪除,因?yàn)椴荒軝z測(cè)外部線程的結(jié)束情況。

Note:守護(hù)線程將在程序關(guān)閉時(shí)直接停止。相關(guān)資源(比如打開的文件、數(shù)據(jù)庫事務(wù)等)可能不會(huì)被妥善地釋放。如果想要線程優(yōu)雅地停止,將線程設(shè)置為非守護(hù)線程,并使用合適的信號(hào)機(jī)制比如Event

class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

group:None。作為將來實(shí)現(xiàn)ThreadGroup類后的保留參數(shù)。

target:可調(diào)用對(duì)象,將被run()方法調(diào)用

name:線程名稱。默認(rèn)構(gòu)建Thread-N形式的唯一名稱。

args:target調(diào)用需要接收的位置參數(shù),元組形式

kwargs:target調(diào)用需要接收的關(guān)鍵字參數(shù),字典形式

daemon:傳遞一個(gè)布爾值,標(biāo)記該線程是否為守護(hù)線程。None表示繼承創(chuàng)建該線程的當(dāng)前線程的daemon屬性。

如果子類繼承Thread并重寫構(gòu)造器,必須確保在執(zhí)行線程的其他操作前在構(gòu)造器中調(diào)用Thread.__init__()

start()
開啟線程。每個(gè)線程最多只能調(diào)用一次,否則拋出RuntimeError異常。它將在一個(gè)多帶帶的控制線程調(diào)用線程對(duì)象的run()方法。

run()
定義線程功能的方法,通常在子類中重寫。標(biāo)準(zhǔn)的run()方法調(diào)用傳入構(gòu)造器的可調(diào)用對(duì)象target(存在的話),并使用args和kwargs分別作為target的位置參數(shù)和關(guān)鍵字參數(shù)。

# 創(chuàng)建Thread的實(shí)例,傳給它一個(gè)函數(shù)

from threading import Thread
from time import sleep, ctime

sleep_time = [4, 2]


def task(task_tag, sleep_tag):
    print("task", task_tag, "started at:", ctime())
    sleep(sleep_tag)
    print("task", task_tag, "done at:", ctime())


def main():
    print("Main thread started at:", ctime())
    threads = []
    nloops = range(len(sleep_time))  # [0, 1]

    for i in nloops:
        t = Thread(target=task, args=(i, sleep_time[i]))
        threads.append(t)

    for i in nloops:
        threads[i].start()  # 啟動(dòng)線程

    for i in nloops:
        threads[i].join()  # 主線程阻塞,直至調(diào)用join()方法的線程終止

    print("Main thread done at:", ctime())


if __name__ == "__main__":
    main()
# 派生Thread的子類,并創(chuàng)建子類的實(shí)例

from threading import Thread
from time import sleep, ctime

sleep_time = [4, 2]


class MyThread(Thread):
    # 重寫run()方法
    def run(self):
        print(self.name, "started at:", ctime())
        self._target(self._args)
        print(self.name, "done at:", ctime())


def task(sleep_tag):
    sleep(sleep_tag)


def main():
    print("Main thread started at:", ctime())
    threads = []
    nloops = range(len(sleep_time))

    for i in nloops:
        t = MyThread(target=task, args=sleep_time[i], name=task.__name__ + str(i))
        threads.append(t)

    for i in nloops:
        threads[i].start()

    for i in nloops:
        threads[i].join()

    print("Main thread done at:", ctime())


if __name__ == "__main__":
    main()

join(timeout=None)
阻塞主線程直到調(diào)用join方法的線程終止(可能是正常執(zhí)行完成,也可能是拋出了未處理的異常)或達(dá)到timeout設(shè)定的時(shí)間??啥啻握{(diào)用。

timeout:阻塞時(shí)間(秒)。如果為None,表示一直阻塞直至調(diào)用join方法的線程終止;如果不為None,表示阻塞的時(shí)間,達(dá)到該時(shí)間后,不管調(diào)用join()方法的線程是否執(zhí)行完成,繼續(xù)執(zhí)行主線程或其他啟動(dòng)的線程。

如果線程調(diào)用join()方法可能導(dǎo)致死鎖,或在調(diào)用start()之前調(diào)用join(),拋出RuntimeError異常。

name
獲取或設(shè)置線程名稱。多個(gè)線程可能名稱相同,初始值由構(gòu)造器設(shè)置。

ident
線程標(biāo)識(shí)符,如果為None說明該線程未啟動(dòng)。當(dāng)一個(gè)線程退出,新的線程創(chuàng)建,線程標(biāo)識(shí)符可能被回收使用。即使線程退出,該標(biāo)識(shí)符仍可用。

is_alive()
判斷線程是否處于活動(dòng)狀態(tài)。

daemon
布爾標(biāo)志,表示這個(gè)線程是否是守護(hù)線程。必須在調(diào)用start()之前設(shè)置,否則拋出RuntimeError異常。初始值繼承自創(chuàng)建該線程的線程。主線程不是守護(hù)線程,因此在主線程中創(chuàng)建的線程daemon屬性默認(rèn)值為False

CPython實(shí)現(xiàn)細(xì)節(jié):在CPython中,由于GIL的原因,一次只有一個(gè)線程能夠執(zhí)行python代碼(即使某些面向性能的庫能克服這個(gè)限制???)。想要python程序更好地利用多核機(jī)器的計(jì)算機(jī)資源(計(jì)算密集型),建議使用multiprocessingconcurrent.futures.ProcessPoolExecutor。如果是同時(shí)運(yùn)行多個(gè)I/O密集型任務(wù),threading仍然不失為一個(gè)合適的模塊

Lock

原語鎖,是同步原語的一種,當(dāng)它處于"locked"狀態(tài)時(shí)不屬于特定線程。在python中,這是目前可用的最低級(jí)的同步原語,實(shí)現(xiàn)自_thread擴(kuò)展模塊。

原語鎖有兩種狀態(tài):locked(鎖定)或unlocked(未鎖定)。創(chuàng)建時(shí)為未鎖定狀態(tài)。
原語鎖有兩種方法:acquire()release()。當(dāng)鎖處于未鎖定狀態(tài)時(shí),acquire()改變其為鎖定狀態(tài)。當(dāng)鎖處于鎖定狀態(tài)時(shí),調(diào)用acquire()方法將導(dǎo)致線程阻塞,直到其他線程調(diào)用release()釋放鎖。

class threading.Lock

acquire(blocking=True, timeout=-1)
獲取鎖。成功返回True,獲取返回False。

blocking:默認(rèn)為True,在獲取到鎖之前阻塞線程;反之即使沒有獲取到鎖也不會(huì)阻塞線程。

timeout:指定線程阻塞的最長時(shí)間,單位為秒;-1表示無限制等待。當(dāng)blocking為False時(shí),禁止指定timeout參數(shù)

release()
釋放鎖。任何線程都可以調(diào)用,不只是獲取了鎖的線程。

鎖更改為未上鎖狀態(tài)后,對(duì)于調(diào)用了acquire()方法而導(dǎo)致阻塞的線程,將由系統(tǒng)決定哪個(gè)線程獲取到鎖。

release()方法只能在上鎖狀態(tài)調(diào)用,否則將拋出RuntimeError異常。

RLock

重入鎖,同步原語的一種,可由同一線程多次獲取已持有的鎖。除了原語鎖的上鎖/解鎖狀態(tài),重入鎖還使用了owning threadrecursion level的概念。在上鎖狀態(tài),可能有多個(gè)線程擁有鎖;在解鎖狀態(tài),沒有線程擁有鎖。

acquire()/release()必須成對(duì)出現(xiàn),可以嵌套,只有最后一個(gè)release(即最外層的release)調(diào)用才會(huì)最終釋放鎖。

class threading.RLock

acquire(blocking=True, timeout=-1)
使用默認(rèn)參數(shù)調(diào)用時(shí),如果當(dāng)前線程已經(jīng)擁有鎖,增加1次遞歸深度并立即返回;如果是其他線程擁有鎖,阻塞當(dāng)前線程直到鎖被釋放。一旦鎖釋放(遞歸深度為0,此時(shí)鎖不屬于任何線程),各個(gè)線程爭奪鎖,并設(shè)置遞歸深度為1。

release()
釋放鎖且遞歸深度減1。如果調(diào)用后遞歸深度為0,重置鎖為未鎖定狀態(tài)(不屬于任何線程),由其他線程爭奪鎖。如果調(diào)用后遞歸深度非0,鎖仍為上鎖狀態(tài),屬于當(dāng)前線程。

只能由已經(jīng)獲取了鎖的線程調(diào)用,否則拋出RuntimeError異常。

Condition

condition變量總是與某種鎖相聯(lián)系:傳入或者默認(rèn)創(chuàng)建的鎖對(duì)象。傳入鎖對(duì)象適用于多個(gè)condition變量需要共享同一個(gè)鎖的場(chǎng)景。鎖是condition對(duì)象的一部分,不需要對(duì)鎖多帶帶進(jìn)行追蹤。

condition對(duì)象遵循上下文管理協(xié)議:使用with語句在封閉塊內(nèi)獲取關(guān)聯(lián)的鎖對(duì)象,在condition對(duì)象上調(diào)用acquire和release實(shí)際上調(diào)用的是關(guān)聯(lián)鎖的對(duì)應(yīng)方法。

class threading.Condition(lock=None)

條件變量允許一個(gè)或多個(gè)線程等待,直到接收到另一個(gè)線程的通知。

lock參數(shù)必須是LockRLock對(duì)象,作為底層的鎖使用。默認(rèn)使用RLock

acquire(*args)
調(diào)用底層lock對(duì)象的acquire()方法獲取鎖

release()
調(diào)用底層lock對(duì)象的release()方法釋放鎖

wait(timeout=None)
釋放鎖并阻塞當(dāng)前線程直到被另外一個(gè)線程調(diào)用notify()notify_all()喚醒,或者達(dá)到設(shè)置的timeout時(shí)間,任意一種情況都將重新獲取鎖并返回。
只能由已獲取到鎖的線程調(diào)用,否則拋出RuntimeError異常。

3.2版本前該方法始終返回None,3.2版本開始除非超時(shí)會(huì)返回False,其他情況都返回True

wait_for(predicate, timeout=None)
阻塞當(dāng)前線程直到可調(diào)用對(duì)象predicate返回值為True或bool()判斷為True。

wait_for方法將不斷調(diào)用wait()方法直到超時(shí)或滿足predicate返回值為True或bool()判斷為True。

返回值為最后一次執(zhí)行predicate的返回值,如果超時(shí)返回False。

只能由已獲取到鎖的線程調(diào)用,否則拋出RuntimeError異常。

notify(n=1)
喚醒wait()或wait_for()狀態(tài)下的某個(gè)線程。只能由已獲取到鎖的線程調(diào)用,否則拋出RuntimeError異常。

notify_all()
喚醒wait()或wait_for()狀態(tài)下的所有線程。只能由已獲取到鎖的線程調(diào)用,否則拋出RuntimeError異常。

notify()和notify_all()并不釋放鎖。意思是調(diào)用wait()方法的線程不會(huì)立即返回,需要等到調(diào)用notify()和notify_all()的線程釋放鎖之后才返回。

# 生產(chǎn)者-消費(fèi)者模式中Condition的用法

# 消費(fèi)者:
with cv:
    while not an_item_is_available():
        cv.wait()
    get_an_available_item()

# 生產(chǎn)者:
with cv:
    make_an_item_available()
    cv.notify()

# 消費(fèi)者(使用wait_for改進(jìn)):
with cv:
    cv.wait_for(an_item_is_available)
    get_an_available_item()
Semaphore Objects

信號(hào)量對(duì)象管理一個(gè)內(nèi)部計(jì)數(shù)器,隨著調(diào)用acquire()減1,release()調(diào)用加1,但一定不會(huì)小于0。當(dāng)調(diào)用acquire()時(shí)如果計(jì)數(shù)器等于0將會(huì)阻塞線程直到某個(gè)線程調(diào)用release()方法。支持上下文管理器協(xié)議

class threading.Semaphore(value=1)

指定初始計(jì)數(shù)器的信號(hào)量,每調(diào)用一次release()加1,每調(diào)用一次acquire()減1。

acquire(blocking=True, timeout=None)
獲取信號(hào)量。

使用默認(rèn)參數(shù)調(diào)用時(shí):

1. 如果計(jì)數(shù)器大于0,減1并立即返回True
2. 如果計(jì)數(shù)器等于0,阻塞直到某個(gè)線程調(diào)用release()喚醒,喚醒后計(jì)數(shù)器減1并返回True

release()
釋放信號(hào)量。

class threading.BoundedSemaphore(value=1)

邊界信號(hào)量,計(jì)數(shù)器值不能超過設(shè)置的最大邊界。常用于限制資源占用的場(chǎng)景比如數(shù)據(jù)庫連接。

Event Objects

事件是最簡單的線程間通信機(jī)制。事件對(duì)象管理一個(gè)內(nèi)部標(biāo)志,調(diào)用set()時(shí)該標(biāo)志為True,調(diào)用clear()時(shí)該標(biāo)志為False,調(diào)用wait()時(shí)線程阻塞直到標(biāo)志為True

class threading.Event

is_set()
如果事件標(biāo)志為True,返回True

set()
設(shè)置事件標(biāo)志為True。將喚醒所有調(diào)用了wait()而阻塞的線程。

clear()
重置事件標(biāo)志為False。將阻塞所有調(diào)用了wait()的線程。

wait(timeout=None)
阻塞線程直到事件標(biāo)志為True或超時(shí)。

Timer Objects

Timer繼承自Thread,表示經(jīng)過一定時(shí)間后要運(yùn)行的任務(wù)。

class threading.Timer(interval, function, args=None, kwargs=None)

創(chuàng)建定時(shí)器,在interval時(shí)間后運(yùn)行function任務(wù)。

cancel()
終止定時(shí)器并結(jié)束任務(wù)(僅對(duì)待執(zhí)行狀態(tài)中的任務(wù)有效)。


相關(guān)文章

Python 多線程: threading.local類

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/43274.html

相關(guān)文章

  • 通讀Python官方文檔Threading

    摘要:但現(xiàn)在線程沒有優(yōu)先級(jí),沒有線程組,不能被銷毀停止暫停開始和打斷。守護(hù)線程也會(huì)結(jié)束,并強(qiáng)行終止整個(gè)程序。在中,他是目前可用的最底層的同步原語,由模塊提供。當(dāng)處于狀態(tài)時(shí),方法可以將狀態(tài)變?yōu)椋⒘⒓捶祷?。否則會(huì)拋出錯(cuò)誤。對(duì)象實(shí)現(xiàn)某些服務(wù)的共進(jìn)退。 Python的threading模塊松散地基于Java的threading模塊。但現(xiàn)在線程沒有優(yōu)先級(jí),沒有線程組,不能被銷毀、停止、暫停、開始和打...

    jasperyang 評(píng)論0 收藏0
  • Python:線程定位與銷毀

    摘要:而線程則是每秒通過輸出當(dāng)前進(jìn)程內(nèi)所有活躍的線程。如果使用強(qiáng)制手段干掉線程,那么很大幾率出現(xiàn)意想不到的。只是通過來約束這些線程,來決定什么時(shí)候開始調(diào)度,比方說運(yùn)行了多少個(gè)指令就交出,至于誰奪得花魁,得聽操作系統(tǒng)的。 背景 開工前我就覺得有什么不太對(duì)勁,感覺要背鍋。這可不,上班第三天就捅鍋了。 我們有個(gè)了不起的后臺(tái)程序,可以動(dòng)態(tài)加載模塊,并以線程方式運(yùn)行,通過這種形式實(shí)現(xiàn)插件的功能。而模塊...

    Heier 評(píng)論0 收藏0
  • python初學(xué)——網(wǎng)絡(luò)編程FTP服務(wù)器支持多并發(fā)版本

    摘要:擴(kuò)展支持多用戶并發(fā)訪問與線程池。項(xiàng)目請(qǐng)見初學(xué)網(wǎng)絡(luò)編程之服務(wù)器。不允許超過磁盤配額。該文件是一個(gè)使用模塊編寫的線程池類。這一步就做到了線程池的作用。 對(duì)MYFTP項(xiàng)目進(jìn)行升級(jí)。擴(kuò)展支持多用戶并發(fā)訪問與線程池。MYFTP項(xiàng)目請(qǐng)見python初學(xué)——網(wǎng)絡(luò)編程之FTP服務(wù)器。 擴(kuò)展需求 1.在之前開發(fā)的FTP基礎(chǔ)上,開發(fā)支持多并發(fā)的功能2.不能使用SocketServer模塊,必須自己實(shí)現(xiàn)多線...

    oysun 評(píng)論0 收藏0
  • Python入門初涉線程

    摘要:由于線程是操作系統(tǒng)直接支持的執(zhí)行單元,因此,高級(jí)語言通常都內(nèi)置多線程的支持,也不例外,并且,的線程是真正的,而不是模擬出來的線程。多任務(wù)可以由多進(jìn)程完成,也可以由一個(gè)進(jìn)程內(nèi)的多線程完成。是模塊中最重要的類之一,可以使用它來創(chuàng)建線程。 由于線程是操作系統(tǒng)直接支持的執(zhí)行單元,因此,高級(jí)語言通常都內(nèi)置多線程的支持,Python也不例外,并且,Python的線程是真正的Posix Thread...

    chuyao 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<