要介紹Python的 threading 模塊中的 Lock 對(duì)象前, 首先應(yīng)該了解以下兩個(gè)概念:
創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供錦江網(wǎng)站建設(shè)、錦江做網(wǎng)站、錦江網(wǎng)站設(shè)計(jì)、錦江網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、錦江企業(yè)網(wǎng)站模板建站服務(wù),10年錦江做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
1.基本概念 : 指某個(gè)函數(shù)/函數(shù)庫在多線程環(huán)境中被調(diào)用時(shí), 能夠正確地處理多個(gè)線程之間的 共享變量 , 使程序功能正常完成. 多個(gè)線程訪問同一個(gè)對(duì)象時(shí), 如果不用考慮這些線程在運(yùn)行時(shí)環(huán)境下的調(diào)度和交替執(zhí)行, 也不需要進(jìn)行額外的同步, 或者在調(diào)用方進(jìn)行任何其他操作,調(diào)用這個(gè)對(duì)象的行為都可以獲得正確的結(jié)果, 那么這個(gè)對(duì)象就是線程安全的. 或者說: 一個(gè)類或者程序所提供的接口對(duì)于線程來說是 原子操作 或者多個(gè)線程之間的切換不會(huì)導(dǎo)致該接口的執(zhí)行結(jié)果存在二義性, 也就是說我們不用考慮同步的問題.
2.示例 : 比如有間銀行只有1000元, 而兩個(gè)人同時(shí)提領(lǐng)1000元時(shí),就有可能拿到總計(jì)2000元的金額. 為了避免這個(gè)問題, 該間銀行提款時(shí)應(yīng)該使用 互斥鎖 , 即意味著對(duì)同一個(gè)資源處理時(shí), 前一個(gè)提領(lǐng)交易完成后才處理下一筆交易.
3.線程安全意義 :
4.是否線程安全 :
5.資源競(jìng)爭(zhēng) : 即多個(gè)線程對(duì)同一個(gè)資源的改寫時(shí), 存在的一種競(jìng)爭(zhēng). 如果僅僅是讀操作, 則不存在資源競(jìng)爭(zhēng)的情況.
1.基本概念 : 因?yàn)榇嬖谏鲜鏊f的 線程安全與資源競(jìng)爭(zhēng) 的情況, 所以引入了 線程鎖 . 即通過鎖來進(jìn)行資源請(qǐng)求的限制, 以保證同步執(zhí)行,避免資源被污染或預(yù)期結(jié)果不符. 線程鎖存在兩種狀態(tài): 鎖定(locked)和非鎖定(unlocked).
2.基本方法 :
3.使用示例 :
上述示例如果在不加鎖的情況下, 將會(huì)出現(xiàn)打印順序混亂的情況, 不過最終結(jié)果都是正確的, 因?yàn)榧词咕€程交替執(zhí)行, 但最終的結(jié)果都是一致.
目錄
眾所周知,CPU是計(jì)算機(jī)的核心,它承擔(dān)了所有的計(jì)算任務(wù)。而操作系統(tǒng)是計(jì)算機(jī)的管理者,是一個(gè)大管家,它負(fù)責(zé)任務(wù)的調(diào)度,資源的分配和管理,統(tǒng)領(lǐng)整個(gè)計(jì)算機(jī)硬件。應(yīng)用程序是具有某種功能的程序,程序運(yùn)行與操作系統(tǒng)之上
在很早的時(shí)候計(jì)算機(jī)并沒有線程這個(gè)概念,但是隨著時(shí)代的發(fā)展,只用進(jìn)程來處理程序出現(xiàn)很多的不足。如當(dāng)一個(gè)進(jìn)程堵塞時(shí),整個(gè)程序會(huì)停止在堵塞處,并且如果頻繁的切換進(jìn)程,會(huì)浪費(fèi)系統(tǒng)資源。所以線程出現(xiàn)了
線程是能擁有資源和獨(dú)立運(yùn)行的最小單位,也是程序執(zhí)行的最小單位。一個(gè)進(jìn)程可以擁有多個(gè)線程,而且屬于同一個(gè)進(jìn)程的多個(gè)線程間會(huì)共享該進(jìn)行的資源
① 200 多本 Python 電子書(和經(jīng)典的書籍)應(yīng)該有
② Python標(biāo)準(zhǔn)庫資料(最全中文版)
③ 項(xiàng)目源碼(四五十個(gè)有趣且可靠的練手項(xiàng)目及源碼)
④ Python基礎(chǔ)入門、爬蟲、網(wǎng)絡(luò)開發(fā)、大數(shù)據(jù)分析方面的視頻(適合小白學(xué)習(xí))
⑤ Python學(xué)習(xí)路線圖(告別不入流的學(xué)習(xí))
私信我01即可獲取大量Python學(xué)習(xí)資源
進(jìn)程時(shí)一個(gè)具有一定功能的程序在一個(gè)數(shù)據(jù)集上的一次動(dòng)態(tài)執(zhí)行過程。進(jìn)程由程序,數(shù)據(jù)集合和進(jìn)程控制塊三部分組成。程序用于描述進(jìn)程要完成的功能,是控制進(jìn)程執(zhí)行的指令集;數(shù)據(jù)集合是程序在執(zhí)行時(shí)需要的數(shù)據(jù)和工作區(qū);程序控制塊(PCB)包含程序的描述信息和控制信息,是進(jìn)程存在的唯一標(biāo)志
在Python中,通過兩個(gè)標(biāo)準(zhǔn)庫 thread 和 Threading 提供對(duì)線程的支持, threading 對(duì) thread 進(jìn)行了封裝。 threading 模塊中提供了 Thread , Lock , RLOCK , Condition 等組件
在Python中線程和進(jìn)程的使用就是通過 Thread 這個(gè)類。這個(gè)類在我們的 thread 和 threading 模塊中。我們一般通過 threading 導(dǎo)入
默認(rèn)情況下,只要在解釋器中,如果沒有報(bào)錯(cuò),則說明線程可用
守護(hù)模式:
現(xiàn)在我們程序代碼中,有多個(gè)線程, 并且在這個(gè)幾個(gè)線程中都會(huì)去 操作同一部分內(nèi)容,那么如何實(shí)現(xiàn)這些數(shù)據(jù)的共享呢?
這時(shí),可以使用 threading庫里面的鎖對(duì)象 Lock 去保護(hù)
Lock 對(duì)象的acquire方法 是申請(qǐng)鎖
每個(gè)線程在操作共享數(shù)據(jù)對(duì)象之前,都應(yīng)該申請(qǐng)獲取操作權(quán),也就是調(diào)用該共享數(shù)據(jù)對(duì)象對(duì)應(yīng)的鎖對(duì)象的acquire方法,如果線程A 執(zhí)行了 acquire() 方法,別的線程B 已經(jīng)申請(qǐng)到了這個(gè)鎖, 并且還沒有釋放,那么 線程A的代碼就在此處 等待 線程B 釋放鎖,不去執(zhí)行后面的代碼。
直到線程B 執(zhí)行了鎖的 release 方法釋放了這個(gè)鎖, 線程A 才可以獲取這個(gè)鎖,就可以執(zhí)行下面的代碼了
如:
到在使用多線程時(shí),如果數(shù)據(jù)出現(xiàn)和自己預(yù)期不符的問題,就可以考慮是否是共享的數(shù)據(jù)被調(diào)用覆蓋的問題
使用 threading 庫里面的鎖對(duì)象 Lock 去保護(hù)
Python中的多進(jìn)程是通過multiprocessing包來實(shí)現(xiàn)的,和多線程的threading.Thread差不多,它可以利用multiprocessing.Process對(duì)象來創(chuàng)建一個(gè)進(jìn)程對(duì)象。這個(gè)進(jìn)程對(duì)象的方法和線程對(duì)象的方法差不多也有start(), run(), join()等方法,其中有一個(gè)方法不同Thread線程對(duì)象中的守護(hù)線程方法是setDeamon,而Process進(jìn)程對(duì)象的守護(hù)進(jìn)程是通過設(shè)置daemon屬性來完成的
守護(hù)模式:
其使用方法和線程的那個(gè) Lock 使用方法類似
Manager的作用是提供多進(jìn)程共享的全局變量,Manager()方法會(huì)返回一個(gè)對(duì)象,該對(duì)象控制著一個(gè)服務(wù)進(jìn)程,該進(jìn)程中保存的對(duì)象運(yùn)行其他進(jìn)程使用代理進(jìn)行操作
語法:
線程池的基類是 concurrent.futures 模塊中的 Executor , Executor 提供了兩個(gè)子類,即 ThreadPoolExecutor 和 ProcessPoolExecutor ,其中 ThreadPoolExecutor 用于創(chuàng)建線程池,而 ProcessPoolExecutor 用于創(chuàng)建進(jìn)程池
如果使用線程池/進(jìn)程池來管理并發(fā)編程,那么只要將相應(yīng)的 task 函數(shù)提交給線程池/進(jìn)程池,剩下的事情就由線程池/進(jìn)程池來搞定
Exectuor 提供了如下常用方法:
程序?qū)?task 函數(shù)提交(submit)給線程池后,submit 方法會(huì)返回一個(gè) Future 對(duì)象,F(xiàn)uture 類主要用于獲取線程任務(wù)函數(shù)的返回值。由于線程任務(wù)會(huì)在新線程中以異步方式執(zhí)行,因此,線程執(zhí)行的函數(shù)相當(dāng)于一個(gè)“將來完成”的任務(wù),所以 Python 使用 Future 來代表
Future 提供了如下方法:
使用線程池來執(zhí)行線程任務(wù)的步驟如下:
最佳線程數(shù)目 = ((線程等待時(shí)間+線程CPU時(shí)間)/線程CPU時(shí)間 )* CPU數(shù)目
也可以低于 CPU 核心數(shù)
使用線程池來執(zhí)行線程任務(wù)的步驟如下:
關(guān)于進(jìn)程的開啟代碼一定要放在 if __name__ == '__main__': 代碼之下,不能放到函數(shù)中或其他地方
開啟進(jìn)程的技巧
開啟進(jìn)程的數(shù)量最好低于最大 CPU 核心數(shù)
并發(fā):邏輯上具備同時(shí)處理多個(gè)任務(wù)的能力。
并行:物理上在同一時(shí)刻執(zhí)行多個(gè)并發(fā)任務(wù)。
舉例:開個(gè)QQ,開了一個(gè)進(jìn)程,開了微信,開了一個(gè)進(jìn)程。在QQ這個(gè)進(jìn)程里面,傳輸文字開一個(gè)線程、傳輸語音開了一個(gè)線程、彈出對(duì)話框又開了一個(gè)線程。
總結(jié):開一個(gè)軟件,相當(dāng)于開了一個(gè)進(jìn)程。在這個(gè)軟件運(yùn)行的過程里,多個(gè)工作同時(shí)運(yùn)轉(zhuǎn),完成了QQ的運(yùn)行,那么這個(gè)多個(gè)工作分別有多個(gè)線程。
線程和進(jìn)程之間的區(qū)別:
進(jìn)程在python中的使用,對(duì)模塊threading進(jìn)行操作,調(diào)用的這個(gè)三方庫??梢酝ㄟ^ help(threading) 了解其中的方法、變量使用情況。也可以使用 dir(threading) 查看目錄結(jié)構(gòu)。
current_thread_num = threading.active_count() # 返回正在運(yùn)行的線程數(shù)量
run_thread_len = len(threading.enumerate()) # 返回正在運(yùn)行的線程數(shù)量
run_thread_list = threading.enumerate() # 返回當(dāng)前運(yùn)行線程的列表
t1=threading.Thread(target=dance) #創(chuàng)建兩個(gè)子線程,參數(shù)傳遞為函數(shù)名
t1.setDaemon(True) # 設(shè)置守護(hù)進(jìn)程,守護(hù)進(jìn)程:主線程結(jié)束時(shí)自動(dòng)退出子線程。
t1.start() # 啟動(dòng)子線程
t1.join() # 等待進(jìn)程結(jié)束 exit()`# 主線程退出,t1子線程設(shè)置了守護(hù)進(jìn)程,會(huì)自動(dòng)退出。其他子線程會(huì)繼續(xù)執(zhí)行。
網(wǎng)站欄目:python線程庫函數(shù),python中線程
本文來源:http://jinyejixie.com/article38/hojjsp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、全網(wǎng)營(yíng)銷推廣、外貿(mào)網(wǎng)站建設(shè)、搜索引擎優(yōu)化、動(dòng)態(tài)網(wǎng)站、品牌網(wǎng)站設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)