欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python低層多線程接口_thread模塊的用法和特性

 更新時(shí)間:2024年10月03日 12:19:37   作者:V1ncent Chen  
這篇文章主要介紹了Python低層多線程接口_thread模塊的用法和特性,_thread是python標(biāo)準(zhǔn)庫(kù)中的一個(gè)低層多線程API,可以在進(jìn)程中啟動(dòng)線程來(lái)處理任務(wù),并且提供了簡(jiǎn)單的鎖機(jī)制來(lái)控制共享資源的同步訪問(wèn),本文就_thread模塊的用法和特性做個(gè)簡(jiǎn)單的演示,需要的朋友可以參考下

一、進(jìn)程和線程的區(qū)別

并行(多任務(wù)處理)是現(xiàn)代操作系統(tǒng)的基本特性,一個(gè)程序可以同時(shí)處理很多任務(wù)而不被阻塞。多任務(wù)處理的基本方式有兩種:進(jìn)程分支和線程派生。

進(jìn)程分支就是從當(dāng)前進(jìn)程復(fù)制一個(gè)程序副本,程序中的內(nèi)存副本,文件描述符等都會(huì)被復(fù)制,子進(jìn)程改變一個(gè)全局對(duì)象只是修改本地的副本,不會(huì)影響到父進(jìn)程。常用在啟動(dòng)獨(dú)立的程序。

線程派生和進(jìn)程分支類(lèi)似,但是子線程依然在原進(jìn)程中運(yùn)行,所有的子線程都會(huì)共享進(jìn)程中的全局對(duì)象,相對(duì)于進(jìn)程分支,少了一個(gè)"復(fù)制"的操作,因此更加輕量化,且由于共享進(jìn)程對(duì)象,相當(dāng)于自帶了線程間的通信機(jī)制(進(jìn)程間的通信則需要借助管道,套接字,信號(hào)等外部工具)。常用在處理一些輕量級(jí)任務(wù)。

但這些共享對(duì)象的訪問(wèn)可能出現(xiàn)沖突,_thread也提供了鎖機(jī)制來(lái)同步化對(duì)象訪問(wèn),例如修改一個(gè)對(duì)象時(shí),先獲取鎖,完成后再釋放,這樣就可以保證任意時(shí)間點(diǎn),最多能有1個(gè)線程能修改這個(gè)共享對(duì)象,防止出現(xiàn)混亂。

二、_thread模塊的用法

_thread模塊中的start_new_thread可以開(kāi)啟一個(gè)新的線程并運(yùn)行指定程序。

2.1 派生線程

當(dāng)程序啟動(dòng)時(shí),其實(shí)它就已經(jīng)啟動(dòng)了一個(gè)線程,這個(gè)就是主線程。通過(guò)_thread.start_new_thread方法,傳入一個(gè)函數(shù)對(duì)象和一個(gè)參數(shù)元組,就可以開(kāi)啟新線程來(lái)執(zhí)行所傳入的函數(shù)對(duì)象。簡(jiǎn)單的演示如下:

import _thread as thread
def func(id):
    print('我是 {} 號(hào)子線程'.format(id))
for i in range(5):
    thread.start_new_thread(func,(i,))

上面代碼執(zhí)行示意圖如下:for循環(huán)執(zhí)行了5次start_new_thread,這會(huì)開(kāi)啟5個(gè)線程,每個(gè)線程去執(zhí)行func函數(shù)。因?yàn)榫€程是并行的,所以輸出的順序并不是0,1,2,3,4而是混亂的。注意3,4號(hào)子線程打印出現(xiàn)了重疊,這是因?yàn)樗鼈児蚕硪粋€(gè)標(biāo)準(zhǔn)輸出流,而我們沒(méi)有做同步化訪問(wèn)控制,因而它們同時(shí)打印輸出。

2.2 同步化訪問(wèn)控制

由于子線程可以共享進(jìn)程中的資源,這既是一個(gè)優(yōu)勢(shì)(方便線程間通信),也帶來(lái)了共享資源訪問(wèn)的問(wèn)題,如果多個(gè)子線程同時(shí)修改一個(gè)共享資源,那么就容易出現(xiàn)沖突,例如上面的輸出重疊。

為了解決這類(lèi)問(wèn)題,_thread模塊中的allocate_lock方法提供了一個(gè)簡(jiǎn)單的鎖機(jī)制來(lái)控制共享訪問(wèn),每次獲取共享資源時(shí)先獲取鎖,可以保證任何時(shí)間點(diǎn)最多只有1個(gè)線程可以訪問(wèn)該資源。示例如下:

import _thread as thread
lock = thread.allocate_lock()    # 定義一個(gè)鎖
def func(id):
    with lock:    # 用上下文管理器自動(dòng)控制鎖的獲取和釋放
        print('我是 {} 號(hào)子線程'.format(id))
for i in range(5):
    thread.start_new_thread(func,(i,))

with lock會(huì)自動(dòng)管理鎖對(duì)象的獲取和釋放,默認(rèn)線程會(huì)一直等待直到鎖的獲取,如果想要更精細(xì)的控制可以使用下面的方式:

lock.acquire()    # 獲取鎖
print('我是 {} 號(hào)子線程'.format(id))
lock.release()    # 釋放鎖

lock.acquire()有2個(gè)可選的參數(shù):blocking=True代表無(wú)法獲取鎖時(shí)等待,blocking=False代表如無(wú)法立刻獲取鎖則返回。timeout=-1代表等待的秒數(shù)(-1代表無(wú)限等待),此參數(shù)只有在blocking設(shè)置為T(mén)rue時(shí)才能指定。

2.3 子線程的退出控制

_thread派生子線程后,如果主線程運(yùn)行完畢,而子線程依然在運(yùn)行中,那么所有子線程就會(huì)隨著主線程的退出而被終止。

我們?cè)谧舆M(jìn)程中增加一個(gè)sleep來(lái)模擬長(zhǎng)時(shí)間任務(wù),讓其運(yùn)行時(shí)長(zhǎng)超過(guò)主線程。將下面的代碼保存到一個(gè)thread1.py中,以一個(gè)獨(dú)立進(jìn)程啟動(dòng):

import _thread as thread, time
lock = thread.allocate_lock()    # 定義一個(gè)鎖
def func(id):
    time.sleep(id)    # 子線程會(huì)睡眠,運(yùn)行時(shí)長(zhǎng)將超過(guò)主線程
    with lock:
        print('我是 {} 號(hào)子線程'.format(id))
for i in range(5):
    thread.start_new_thread(func,(i,))
print('主線程結(jié)束,退出...')    # 主線程退出時(shí)打印提示

可以看到,主線程打印了退出提示,但子線程卻沒(méi)有任何輸出,這是因?yàn)橹骶€程運(yùn)行的時(shí)間非常短,當(dāng)其退出時(shí),所有子線程都終止了。這種情況顯然不是我們想看到的。示例圖如下:

2.3.1 通過(guò)sleep等待子線程運(yùn)行結(jié)束

為了解決上面的問(wèn)題,一個(gè)簡(jiǎn)單的解決方案可以在主線程中加一個(gè)sleep,讓其等待一段時(shí)間再退出,但這個(gè)時(shí)間我們只能預(yù)估。在上面的代碼基礎(chǔ)上,增加一個(gè)time.sleep(3),讓主線程退出前等待3秒,保存為thread2.py,再次執(zhí)行:

import _thread as thread, time
lock = thread.allocate_lock()    # 定義一個(gè)鎖
def func(id):
    time.sleep(id)    # 子線程會(huì)睡眠,運(yùn)行時(shí)長(zhǎng)將超過(guò)主線程
    with lock:
        print('我是 {} 號(hào)子線程'.format(id))
for i in range(5):
    thread.start_new_thread(func,(i,))
time.sleep(3)    # 主線程等待3秒再退出
print('主線程結(jié)束,退出...')    # 主線程退出時(shí)打印提示

可以看到部分子進(jìn)程運(yùn)行完畢,但還有部分子進(jìn)程未完成,因此這種方法不是很準(zhǔn)確,雖然你可以給一個(gè)足夠長(zhǎng)的時(shí)間來(lái)保證所有子進(jìn)程運(yùn)行結(jié)束,但如果進(jìn)程長(zhǎng)時(shí)間不結(jié)束,也會(huì)占用系統(tǒng)資源。

2.3.2 通過(guò)鎖的狀態(tài)監(jiān)測(cè)子進(jìn)程結(jié)束

_thread.allocate_lock除了可以控制共享對(duì)象的訪問(wèn),還可以用來(lái)傳遞全局狀態(tài),下面定義了包含5把鎖的列表,每個(gè)子線程執(zhí)行完成后會(huì)去獲取其中對(duì)應(yīng)位置上的鎖,在主線程中通過(guò)lock.locked()來(lái)檢查是否所有的鎖都被獲取,當(dāng)所有鎖都被獲取時(shí)(代表所有子線程都結(jié)束),主線程退出。將下面代碼保存到thread3.py中,再次運(yùn)行:

import _thread as thread, time
lock = thread.allocate_lock()    # 定義一個(gè)鎖
exit_locks = [thread.allocate_lock() for I in range(5)]   # 定義一個(gè)列表,包含5把鎖,對(duì)應(yīng)稍后啟動(dòng)的5個(gè)子線程
def func(id):
    time.sleep(id)    # 子線程會(huì)睡眠,運(yùn)行時(shí)長(zhǎng)將超過(guò)主線程
    with lock:
        print('我是 {} 號(hào)子線程'.format(id))
    exit_locks[id].acquire()    # 執(zhí)行完成后獲取exit_locks中對(duì)應(yīng)位置的鎖
for i in range(5):
    thread.start_new_thread(func,(i,))
for lock in exit_locks:
    while not lock.locked(): pass    # lock.locked()檢測(cè)鎖是否已被獲取
print('主線程結(jié)束,退出...')    # 主線程退出時(shí)打印提示

測(cè)試時(shí)可以發(fā)現(xiàn),主線程會(huì)在所有子線程執(zhí)行完畢后立刻退出,即不會(huì)提前導(dǎo)致子線程終止,也不會(huì)推遲浪費(fèi)系統(tǒng)資源。

2.3.3 通過(guò)共享變量監(jiān)測(cè)子進(jìn)程結(jié)束

由于子線程可以共享進(jìn)程中的變量,因此子線程中對(duì)共享對(duì)象的修改在主線程也可以看到,我們可以將上面的鎖替換為簡(jiǎn)單的變量,可以達(dá)到相同的效果,下面使用一個(gè)共享列表,通過(guò)在子線程中修改變量值傳遞狀態(tài),將下面代碼保存為thread4.py并執(zhí)行:

import _thread as thread, time
lock = thread.allocate_lock()    # 定義一個(gè)鎖
exit_flags = [False]*5   # 定義一個(gè)全局共享列表,包含5個(gè)布爾變量False
def func(id):
    time.sleep(id)    # 子線程會(huì)睡眠,運(yùn)行時(shí)長(zhǎng)將超過(guò)主線程
    with lock:
        print('我是 {} 號(hào)子線程'.format(id))
    exit_flags[id] = True    # 執(zhí)行完成后將共享列表中對(duì)應(yīng)位置的值改為T(mén)rue
for i in range(5):
    thread.start_new_thread(func,(i,))
while False in exit_flags:pass    # 檢測(cè)列表中是否有False,如果全部為T(mén)ure,代表所有子線程執(zhí)行完畢
print('主線程結(jié)束,退出...')    # 主線程退出時(shí)打印提示

可以看到主線程會(huì)等待子線程執(zhí)行完畢后退出,這種方式相比上面可以節(jié)約鎖分配的資源,看上去也更加簡(jiǎn)單。

以上即是_thread模塊的基本用法?;赺thread模塊還有高級(jí)的threading模塊,_threading模塊是基于類(lèi)和對(duì)象的高級(jí)接口,并提供了額外的控制工具,例如threading.join()可以實(shí)現(xiàn)等待子進(jìn)程退出。

到此這篇關(guān)于Python低層多線程接口_thread模塊的用法和特性的文章就介紹到這了,更多相關(guān)Python低層多線程接口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python selenium抓取虎牙短視頻代碼實(shí)例

    Python selenium抓取虎牙短視頻代碼實(shí)例

    這篇文章主要介紹了Python selenium抓取虎牙短視頻代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Python?搭建?FastAPI?項(xiàng)目的詳細(xì)過(guò)程

    Python?搭建?FastAPI?項(xiàng)目的詳細(xì)過(guò)程

    這篇文章主要介紹了Python搭建FastAPI項(xiàng)目的過(guò)程,本文通過(guò)圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • Python shelve模塊實(shí)現(xiàn)解析

    Python shelve模塊實(shí)現(xiàn)解析

    這篇文章主要介紹了Python shelve模塊實(shí)現(xiàn)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • Python開(kāi)發(fā)文字版密室逃脫游戲的實(shí)例(含代碼)

    Python開(kāi)發(fā)文字版密室逃脫游戲的實(shí)例(含代碼)

    密室逃脫游戲是一種頗受歡迎的解謎類(lèi)游戲,玩家通常需要通過(guò)觀察、推理、合作等方式解決一系列難題,以逃脫困境,在這篇博文中,我們將使用Python開(kāi)發(fā)一個(gè)文字版密室逃脫游戲,旨在通過(guò)簡(jiǎn)單的文本交互來(lái)呈現(xiàn)游戲的趣味性與挑戰(zhàn)性
    2025-04-04
  • Python ckeditor富文本編輯器代碼實(shí)例解析

    Python ckeditor富文本編輯器代碼實(shí)例解析

    這篇文章主要介紹了Python ckeditor富文本編輯器代碼實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • Python貪心算法Greedy Algorithm解決案例小結(jié)

    Python貪心算法Greedy Algorithm解決案例小結(jié)

    這篇文章主要為大家介紹了Python貪心算法Greedy Algorithm解決案例小結(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • Python實(shí)現(xiàn)TOPSIS分析法的示例代碼

    Python實(shí)現(xiàn)TOPSIS分析法的示例代碼

    TOPSIS法是一種常用的綜合評(píng)價(jià)方法,其能充分利用原始數(shù)據(jù)的信息,其結(jié)果能精確反應(yīng)各評(píng)價(jià)方案之間的差距。本文將利用Python實(shí)現(xiàn)這一方法,感興趣的可以了解一下
    2023-02-02
  • 關(guān)于python3安裝pip及requests庫(kù)的導(dǎo)入問(wèn)題

    關(guān)于python3安裝pip及requests庫(kù)的導(dǎo)入問(wèn)題

    小編最近快畢業(yè)了,閑著無(wú)事學(xué)習(xí)下python的內(nèi)容在學(xué)習(xí)到requsets庫(kù)的導(dǎo)入問(wèn)題時(shí)遇到一些問(wèn)題,通過(guò)查找相關(guān)資料問(wèn)題順利解決,今天小編把問(wèn)題解決思路及注意事項(xiàng)分享給大家供大家參考學(xué)習(xí)
    2021-05-05
  • Python全局變量用法實(shí)例分析

    Python全局變量用法實(shí)例分析

    這篇文章主要介紹了Python全局變量用法,結(jié)合實(shí)例形式分析了Python中全局變量的定義、使用方法與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2016-07-07
  • 基于Tensorflow使用CPU而不用GPU問(wèn)題的解決

    基于Tensorflow使用CPU而不用GPU問(wèn)題的解決

    今天小編就為大家分享一篇基于Tensorflow使用CPU而不用GPU問(wèn)題的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-02-02

最新評(píng)論