欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

python線程函數(shù) python 多線程 函數(shù)

一篇文章帶你深度解析Python線程和進程

使用Python中的線程模塊,能夠同時運行程序的不同部分,并簡化設(shè)計。如果你已經(jīng)入門Python,并且想用線程來提升程序運行速度的話,希望這篇教程會對你有所幫助。

創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都做網(wǎng)站、網(wǎng)站制作、中山網(wǎng)絡(luò)推廣、成都微信小程序、中山網(wǎng)絡(luò)營銷、中山企業(yè)策劃、中山品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供中山建站搭建服務(wù),24小時服務(wù)熱線:18980820575,官方網(wǎng)址:chinadenli.net

線程與進程

什么是進程

進程是系統(tǒng)進行資源分配和調(diào)度的一個獨立單位 進程是具有一定獨立功能的程序關(guān)于某個數(shù)據(jù)集合上的一次運行活動,進程是系統(tǒng)進行資源分配和調(diào)度的一個獨立單位。每個進程都有自己的獨立內(nèi)存空間,不同進程通過進程間通信來通信。由于進程比較重量,占據(jù)獨立的內(nèi)存,所以上下文進程間的切換開銷(棧、寄存器、虛擬內(nèi)存、文件句柄等)比較大,但相對比較穩(wěn)定安全。

什么是線程

CPU調(diào)度和分派的基本單位 線程是進程的一個實體,是CPU調(diào)度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統(tǒng)資源,只擁有一點在運行中必不可少的資源(如程序計數(shù)器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源。線程間通信主要通過共享內(nèi)存,上下文切換很快,資源開銷較少,但相比進程不夠穩(wěn)定容易丟失數(shù)據(jù)。

進程與線程的關(guān)系圖

線程與進程的區(qū)別:

進程

現(xiàn)實生活中,有很多的場景中的事情是同時進行的,比如開車的時候 手和腳共同來駕駛 汽車 ,比如唱歌跳舞也是同時進行的,再比如邊吃飯邊打電話;試想如果我們吃飯的時候有一個領(lǐng)導(dǎo)來電,我們肯定是立刻就接聽了。但是如果你吃完飯再接聽或者回電話,很可能會被開除。

注意:

多任務(wù)的概念

什么叫 多任務(wù) 呢?簡單地說,就是操作系統(tǒng)可以同時運行多個任務(wù)。打個比方,你一邊在用瀏覽器上網(wǎng),一邊在聽MP3,一邊在用Word趕作業(yè),這就是多任務(wù),至少同時有3個任務(wù)正在運行。還有很多任務(wù)悄悄地在后臺同時運行著,只是桌面上沒有顯示而已。

現(xiàn)在,多核CPU已經(jīng)非常普及了,但是,即使過去的單核CPU,也可以執(zhí)行多任務(wù)。由于CPU執(zhí)行代碼都是順序執(zhí)行的,那么,單核CPU是怎么執(zhí)行多任務(wù)的呢?

答案就是操作系統(tǒng)輪流讓各個任務(wù)交替執(zhí)行,任務(wù)1執(zhí)行0.01秒,切換到任務(wù)2,任務(wù)2執(zhí)行0.01秒,再切換到任務(wù)3,執(zhí)行0.01秒,這樣反復(fù)執(zhí)行下去。表面上看,每個任務(wù)都是交替執(zhí)行的,但是,由于CPU的執(zhí)行速度實在是太快了,我們感覺就像所有任務(wù)都在同時執(zhí)行一樣。

真正的并行執(zhí)行多任務(wù)只能在多核CPU上實現(xiàn),但是,由于任務(wù)數(shù)量遠遠多于CPU的核心數(shù)量,所以,操作系統(tǒng)也會自動把很多任務(wù)輪流調(diào)度到每個核心上執(zhí)行。 其實就是CPU執(zhí)行速度太快啦!以至于我們感受不到在輪流調(diào)度。

并行與并發(fā)

并行(Parallelism)

并行:指兩個或兩個以上事件(或線程)在同一時刻發(fā)生,是真正意義上的不同事件或線程在同一時刻,在不同CPU資源呢上(多核),同時執(zhí)行。

特點

并發(fā)(Concurrency)

指一個物理CPU(也可以多個物理CPU) 在若干道程序(或線程)之間多路復(fù)用,并發(fā)性是對有限物理資源強制行使多用戶共享以提高效率。

特點

multiprocess.Process模塊

process模塊是一個創(chuàng)建進程的模塊,借助這個模塊,就可以完成進程的創(chuàng)建。

語法:Process([group [, target [, name [, args [, kwargs]]]]])

由該類實例化得到的對象,表示一個子進程中的任務(wù)(尚未啟動)。

注意:1. 必須使用關(guān)鍵字方式來指定參數(shù);2. args指定的為傳給target函數(shù)的位置參數(shù),是一個元祖形式,必須有逗號。

參數(shù)介紹:

group:參數(shù)未使用,默認值為None。

target:表示調(diào)用對象,即子進程要執(zhí)行的任務(wù)。

args:表示調(diào)用的位置參數(shù)元祖。

kwargs:表示調(diào)用對象的字典。如kwargs = {'name':Jack, 'age':18}。

name:子進程名稱。

代碼:

除了上面這些開啟進程的方法之外,還有一種以繼承Process的方式開啟進程的方式:

通過上面的研究,我們千方百計實現(xiàn)了程序的異步,讓多個任務(wù)可以同時在幾個進程中并發(fā)處理,他們之間的運行沒有順序,一旦開啟也不受我們控制。盡管并發(fā)編程讓我們能更加充分的利用IO資源,但是也給我們帶來了新的問題。

當(dāng)多個進程使用同一份數(shù)據(jù)資源的時候,就會引發(fā)數(shù)據(jù)安全或順序混亂問題,我們可以考慮加鎖,我們以模擬搶票為例,來看看數(shù)據(jù)安全的重要性。

加鎖可以保證多個進程修改同一塊數(shù)據(jù)時,同一時間只能有一個任務(wù)可以進行修改,即串行的修改。加鎖犧牲了速度,但是卻保證了數(shù)據(jù)的安全。

因此我們最好找尋一種解決方案能夠兼顧:1、效率高(多個進程共享一塊內(nèi)存的數(shù)據(jù))2、幫我們處理好鎖問題。

mutiprocessing模塊為我們提供的基于消息的IPC通信機制:隊列和管道。隊列和管道都是將數(shù)據(jù)存放于內(nèi)存中 隊列又是基于(管道+鎖)實現(xiàn)的,可以讓我們從復(fù)雜的鎖問題中解脫出來, 我們應(yīng)該盡量避免使用共享數(shù)據(jù),盡可能使用消息傳遞和隊列,避免處理復(fù)雜的同步和鎖問題,而且在進程數(shù)目增多時,往往可以獲得更好的可獲展性( 后續(xù)擴展該內(nèi)容 )。

線程

Python的threading模塊

Python 供了幾個用于多線程編程的模塊,包括 thread, threading 和 Queue 等。thread 和 threading 模塊允許程序員創(chuàng)建和管理線程。thread 模塊 供了基本的線程和鎖的支持,而 threading 供了更高級別,功能更強的線程管理的功能。Queue 模塊允許用戶創(chuàng)建一個可以用于多個線程之間 共享數(shù)據(jù)的隊列數(shù)據(jù)結(jié)構(gòu)。

python創(chuàng)建和執(zhí)行線程

創(chuàng)建線程代碼

1. 創(chuàng)建方法一:

2. 創(chuàng)建方法二:

進程和線程都是實現(xiàn)多任務(wù)的一種方式,例如:在同一臺計算機上能同時運行多個QQ(進程),一個QQ可以打開多個聊天窗口(線程)。資源共享:進程不能共享資源,而線程共享所在進程的地址空間和其他資源,同時,線程有自己的棧和棧指針。所以在一個進程內(nèi)的所有線程共享全局變量,但多線程對全局變量的更改會導(dǎo)致變量值得混亂。

代碼演示:

得到的結(jié)果是:

首先需要明確的一點是GIL并不是Python的特性,它是在實現(xiàn)Python解析器(CPython)時所引入的一個概念。就好比C++是一套語言(語法)標準,但是可以用不同的編譯器來編譯成可執(zhí)行代碼。同樣一段代碼可以通過CPython,PyPy,Psyco等不同的Python執(zhí)行環(huán)境來執(zhí)行(其中的JPython就沒有GIL)。

那么CPython實現(xiàn)中的GIL又是什么呢?GIL全稱Global Interpreter Lock為了避免誤導(dǎo),我們還是來看一下官方給出的解釋:

主要意思為:

因此,解釋器實際上被一個全局解釋器鎖保護著,它確保任何時候都只有一個Python線程執(zhí)行。在多線程環(huán)境中,Python 虛擬機按以下方式執(zhí)行:

由于GIL的存在,Python的多線程不能稱之為嚴格的多線程。因為 多線程下每個線程在執(zhí)行的過程中都需要先獲取GIL,保證同一時刻只有一個線程在運行。

由于GIL的存在,即使是多線程,事實上同一時刻只能保證一個線程在運行, 既然這樣多線程的運行效率不就和單線程一樣了嗎,那為什么還要使用多線程呢?

由于以前的電腦基本都是單核CPU,多線程和單線程幾乎看不出差別,可是由于計算機的迅速發(fā)展,現(xiàn)在的電腦幾乎都是多核CPU了,最少也是兩個核心數(shù)的,這時差別就出來了:通過之前的案例我們已經(jīng)知道,即使在多核CPU中,多線程同一時刻也只有一個線程在運行,這樣不僅不能利用多核CPU的優(yōu)勢,反而由于每個線程在多個CPU上是交替執(zhí)行的,導(dǎo)致在不同CPU上切換時造成資源的浪費,反而會更慢。即原因是一個進程只存在一把gil鎖,當(dāng)在執(zhí)行多個線程時,內(nèi)部會爭搶gil鎖,這會造成當(dāng)某一個線程沒有搶到鎖的時候會讓cpu等待,進而不能合理利用多核cpu資源。

但是在使用多線程抓取網(wǎng)頁內(nèi)容時,遇到IO阻塞時,正在執(zhí)行的線程會暫時釋放GIL鎖,這時其它線程會利用這個空隙時間,執(zhí)行自己的代碼,因此多線程抓取比單線程抓取性能要好,所以我們還是要使用多線程的。

GIL對多線程Python程序的影響

程序的性能受到計算密集型(CPU)的程序限制和I/O密集型的程序限制影響,那什么是計算密集型和I/O密集型程序呢?

計算密集型:要進行大量的數(shù)值計算,例如進行上億的數(shù)字計算、計算圓周率、對視頻進行高清解碼等等。這種計算密集型任務(wù)雖然也可以用多任務(wù)完成,但是花費的主要時間在任務(wù)切換的時間,此時CPU執(zhí)行任務(wù)的效率比較低。

IO密集型:涉及到網(wǎng)絡(luò)請求(time.sleep())、磁盤IO的任務(wù)都是IO密集型任務(wù),這類任務(wù)的特點是CPU消耗很少,任務(wù)的大部分時間都在等待IO操作完成(因為IO的速度遠遠低于CPU和內(nèi)存的速度)。對于IO密集型任務(wù),任務(wù)越多,CPU效率越高,但也有一個限度。

當(dāng)然為了避免GIL對我們程序產(chǎn)生影響,我們也可以使用,線程鎖。

LockRLock

常用的資源共享鎖機制:有Lock、RLock、Semphore、Condition等,簡單給大家分享下Lock和RLock。

Lock

特點就是執(zhí)行速度慢,但是保證了數(shù)據(jù)的安全性

RLock

使用鎖代碼操作不當(dāng)就會產(chǎn)生死鎖的情況。

什么是死鎖

死鎖:當(dāng)線程A持有獨占鎖a,并嘗試去獲取獨占鎖b的同時,線程B持有獨占鎖b,并嘗試獲取獨占鎖a的情況下,就會發(fā)生AB兩個線程由于互相持有對方需要的鎖,而發(fā)生的阻塞現(xiàn)象,我們稱為死鎖。即死鎖是指多個進程因競爭資源而造成的一種僵局,若無外力作用,這些進程都將無法向前推進。

所以,在系統(tǒng)設(shè)計、進程調(diào)度等方面注意如何不讓這四個必要條件成立,如何確定資源的合理分配算法,避免進程永久占據(jù)系統(tǒng)資源。

死鎖代碼

python線程間通信

如果各個線程之間各干各的,確實不需要通信,這樣的代碼也十分的簡單。但這一般是不可能的,至少線程要和主線程進行通信,不然計算結(jié)果等內(nèi)容無法取回。而實際情況中要復(fù)雜的多,多個線程間需要交換數(shù)據(jù),才能得到正確的執(zhí)行結(jié)果。

python中Queue是消息隊列,提供線程間通信機制,python3中重名為為queue,queue模塊塊下提供了幾個阻塞隊列,這些隊列主要用于實現(xiàn)線程通信。

在 queue 模塊下主要提供了三個類,分別代表三種隊列,它們的主要區(qū)別就在于進隊列、出隊列的不同。

簡單代碼演示

此時代碼會阻塞,因為queue中內(nèi)容已滿,此時可以在第四個queue.put('蘋果')后面添加timeout,則成為 queue.put('蘋果',timeout=1)如果等待1秒鐘仍然是滿的就會拋出異常,可以捕獲異常。

同理如果隊列是空的,無法獲取到內(nèi)容默認也會阻塞,如果不阻塞可以使用queue.get_nowait()。

在掌握了 Queue 阻塞隊列的特性之后,在下面程序中就可以利用 Queue 來實現(xiàn)線程通信了。

下面演示一個生產(chǎn)者和一個消費者,當(dāng)然都可以多個

使用queue模塊,可在線程間進行通信,并保證了線程安全。

協(xié)程

協(xié)程,又稱微線程,纖程。英文名Coroutine。

協(xié)程是python個中另外一種實現(xiàn)多任務(wù)的方式,只不過比線程更小占用更小執(zhí)行單元(理解為需要的資源)。為啥說它是一個執(zhí)行單元,因為它自帶CPU上下文。這樣只要在合適的時機, 我們可以把一個協(xié)程 切換到另一個協(xié)程。只要這個過程中保存或恢復(fù) CPU上下文那么程序還是可以運行的。

通俗的理解:在一個線程中的某個函數(shù),可以在任何地方保存當(dāng)前函數(shù)的一些臨時變量等信息,然后切換到另外一個函數(shù)中執(zhí)行,注意不是通過調(diào)用函數(shù)的方式做到的,并且切換的次數(shù)以及什么時候再切換到原來的函數(shù)都由開發(fā)者自己確定。

在實現(xiàn)多任務(wù)時,線程切換從系統(tǒng)層面遠不止保存和恢復(fù) CPU上下文這么簡單。操作系統(tǒng)為了程序運行的高效性每個線程都有自己緩存Cache等等數(shù)據(jù),操作系統(tǒng)還會幫你做這些數(shù)據(jù)的恢復(fù)操作。所以線程的切換非常耗性能。但是協(xié)程的切換只是單純的操作CPU的上下文,所以一秒鐘切換個上百萬次系統(tǒng)都抗的住。

greenlet與gevent

為了更好使用協(xié)程來完成多任務(wù),除了使用原生的yield完成模擬協(xié)程的工作,其實python還有的greenlet模塊和gevent模塊,使實現(xiàn)協(xié)程變的更加簡單高效。

greenlet雖說實現(xiàn)了協(xié)程,但需要我們手工切換,太麻煩了,gevent是比greenlet更強大的并且能夠自動切換任務(wù)的模塊。

其原理是當(dāng)一個greenlet遇到IO(指的是input output 輸入輸出,比如網(wǎng)絡(luò)、文件操作等)操作時,比如訪問網(wǎng)絡(luò),就自動切換到其他的greenlet,等到IO操作完成,再在適當(dāng)?shù)臅r候切換回來繼續(xù)執(zhí)行。

模擬耗時操作:

如果有耗時操作也可以換成,gevent中自己實現(xiàn)的模塊,這時候就需要打補丁了。

使用協(xié)程完成一個簡單的二手房信息的爬蟲代碼吧!

以下文章來源于Python專欄 ,作者宋宋

文章鏈接:

python之多線程原理

并發(fā):邏輯上具備同時處理多個任務(wù)的能力。

并行:物理上在同一時刻執(zhí)行多個并發(fā)任務(wù)。

舉例:開個QQ,開了一個進程,開了微信,開了一個進程。在QQ這個進程里面,傳輸文字開一個線程、傳輸語音開了一個線程、彈出對話框又開了一個線程。

總結(jié):開一個軟件,相當(dāng)于開了一個進程。在這個軟件運行的過程里,多個工作同時運轉(zhuǎn),完成了QQ的運行,那么這個多個工作分別有多個線程。

線程和進程之間的區(qū)別:

進程在python中的使用,對模塊threading進行操作,調(diào)用的這個三方庫。可以通過 help(threading) 了解其中的方法、變量使用情況。也可以使用 dir(threading) 查看目錄結(jié)構(gòu)。

current_thread_num = threading.active_count() # 返回正在運行的線程數(shù)量

run_thread_len = len(threading.enumerate()) # 返回正在運行的線程數(shù)量

run_thread_list = threading.enumerate() # 返回當(dāng)前運行線程的列表

t1=threading.Thread(target=dance) #創(chuàng)建兩個子線程,參數(shù)傳遞為函數(shù)名

t1.setDaemon(True) # 設(shè)置守護進程,守護進程:主線程結(jié)束時自動退出子線程。

t1.start() # 啟動子線程

t1.join() # 等待進程結(jié)束 exit()`# 主線程退出,t1子線程設(shè)置了守護進程,會自動退出。其他子線程會繼續(xù)執(zhí)行。

python 怎么實現(xiàn)多線程的

線程也就是輕量級的進程,多線程允許一次執(zhí)行多個線程,Python是多線程語言,它有一個多線程包,GIL也就是全局解釋器鎖,以確保一次執(zhí)行單個線程,一個線程保存GIL并在將其傳遞給下一個線程之前執(zhí)行一些操作,也就產(chǎn)生了并行執(zhí)行的錯覺。

小白都看懂了,Python 中的線程和進程精講,建議收藏

目錄

眾所周知,CPU是計算機的核心,它承擔(dān)了所有的計算任務(wù)。而操作系統(tǒng)是計算機的管理者,是一個大管家,它負責(zé)任務(wù)的調(diào)度,資源的分配和管理,統(tǒng)領(lǐng)整個計算機硬件。應(yīng)用程序是具有某種功能的程序,程序運行與操作系統(tǒng)之上

在很早的時候計算機并沒有線程這個概念,但是隨著時代的發(fā)展,只用進程來處理程序出現(xiàn)很多的不足。如當(dāng)一個進程堵塞時,整個程序會停止在堵塞處,并且如果頻繁的切換進程,會浪費系統(tǒng)資源。所以線程出現(xiàn)了

線程是能擁有資源和獨立運行的最小單位,也是程序執(zhí)行的最小單位。一個進程可以擁有多個線程,而且屬于同一個進程的多個線程間會共享該進行的資源

① 200 多本 Python 電子書(和經(jīng)典的書籍)應(yīng)該有

② Python標準庫資料(最全中文版)

③ 項目源碼(四五十個有趣且可靠的練手項目及源碼)

④ Python基礎(chǔ)入門、爬蟲、網(wǎng)絡(luò)開發(fā)、大數(shù)據(jù)分析方面的視頻(適合小白學(xué)習(xí))

⑤ Python學(xué)習(xí)路線圖(告別不入流的學(xué)習(xí))

私信我01即可獲取大量Python學(xué)習(xí)資源

進程時一個具有一定功能的程序在一個數(shù)據(jù)集上的一次動態(tài)執(zhí)行過程。進程由程序,數(shù)據(jù)集合和進程控制塊三部分組成。程序用于描述進程要完成的功能,是控制進程執(zhí)行的指令集;數(shù)據(jù)集合是程序在執(zhí)行時需要的數(shù)據(jù)和工作區(qū);程序控制塊(PCB)包含程序的描述信息和控制信息,是進程存在的唯一標志

在Python中,通過兩個標準庫 thread 和 Threading 提供對線程的支持, threading 對 thread 進行了封裝。 threading 模塊中提供了 Thread , Lock , RLOCK , Condition 等組件

在Python中線程和進程的使用就是通過 Thread 這個類。這個類在我們的 thread 和 threading 模塊中。我們一般通過 threading 導(dǎo)入

默認情況下,只要在解釋器中,如果沒有報錯,則說明線程可用

守護模式:

現(xiàn)在我們程序代碼中,有多個線程, 并且在這個幾個線程中都會去 操作同一部分內(nèi)容,那么如何實現(xiàn)這些數(shù)據(jù)的共享呢?

這時,可以使用 threading庫里面的鎖對象 Lock 去保護

Lock 對象的acquire方法 是申請鎖

每個線程在操作共享數(shù)據(jù)對象之前,都應(yīng)該申請獲取操作權(quán),也就是調(diào)用該共享數(shù)據(jù)對象對應(yīng)的鎖對象的acquire方法,如果線程A 執(zhí)行了 acquire() 方法,別的線程B 已經(jīng)申請到了這個鎖, 并且還沒有釋放,那么 線程A的代碼就在此處 等待 線程B 釋放鎖,不去執(zhí)行后面的代碼。

直到線程B 執(zhí)行了鎖的 release 方法釋放了這個鎖, 線程A 才可以獲取這個鎖,就可以執(zhí)行下面的代碼了

如:

到在使用多線程時,如果數(shù)據(jù)出現(xiàn)和自己預(yù)期不符的問題,就可以考慮是否是共享的數(shù)據(jù)被調(diào)用覆蓋的問題

使用 threading 庫里面的鎖對象 Lock 去保護

Python中的多進程是通過multiprocessing包來實現(xiàn)的,和多線程的threading.Thread差不多,它可以利用multiprocessing.Process對象來創(chuàng)建一個進程對象。這個進程對象的方法和線程對象的方法差不多也有start(), run(), join()等方法,其中有一個方法不同Thread線程對象中的守護線程方法是setDeamon,而Process進程對象的守護進程是通過設(shè)置daemon屬性來完成的

守護模式:

其使用方法和線程的那個 Lock 使用方法類似

Manager的作用是提供多進程共享的全局變量,Manager()方法會返回一個對象,該對象控制著一個服務(wù)進程,該進程中保存的對象運行其他進程使用代理進行操作

語法:

線程池的基類是 concurrent.futures 模塊中的 Executor , Executor 提供了兩個子類,即 ThreadPoolExecutor 和 ProcessPoolExecutor ,其中 ThreadPoolExecutor 用于創(chuàng)建線程池,而 ProcessPoolExecutor 用于創(chuàng)建進程池

如果使用線程池/進程池來管理并發(fā)編程,那么只要將相應(yīng)的 task 函數(shù)提交給線程池/進程池,剩下的事情就由線程池/進程池來搞定

Exectuor 提供了如下常用方法:

程序?qū)?task 函數(shù)提交(submit)給線程池后,submit 方法會返回一個 Future 對象,F(xiàn)uture 類主要用于獲取線程任務(wù)函數(shù)的返回值。由于線程任務(wù)會在新線程中以異步方式執(zhí)行,因此,線程執(zhí)行的函數(shù)相當(dāng)于一個“將來完成”的任務(wù),所以 Python 使用 Future 來代表

Future 提供了如下方法:

使用線程池來執(zhí)行線程任務(wù)的步驟如下:

最佳線程數(shù)目 = ((線程等待時間+線程CPU時間)/線程CPU時間 )* CPU數(shù)目

也可以低于 CPU 核心數(shù)

使用線程池來執(zhí)行線程任務(wù)的步驟如下:

關(guān)于進程的開啟代碼一定要放在 if __name__ == '__main__': 代碼之下,不能放到函數(shù)中或其他地方

開啟進程的技巧

開啟進程的數(shù)量最好低于最大 CPU 核心數(shù)

python多線程全局變量和鎖

1.python中數(shù)據(jù)類型,int,float,復(fù)數(shù),字符,元組,做全局變量時需要在函數(shù)里面用global申明變量,才能對變量進行操作。

而,對象,列表,詞典,不需要聲明,直接就是全局的。

2.線程鎖mutex=threading.Lock()

創(chuàng)建后就是全局的。線程調(diào)用函數(shù)可以直接在函數(shù)中使用。

mutex.acquire()開啟鎖

mutex=release()關(guān)閉鎖

要注意,死鎖的情況發(fā)生。

注意運行效率的變化:

正常1秒,完成56997921

加鎖之后,1秒只運行了531187,相差10倍多。

3.繼承.threading.Thread的類,無法調(diào)用__init__函數(shù),無法在創(chuàng)建對象時初始化新建的屬性。

4.線程在cpu的執(zhí)行,有隨機性

5. 新建線程時,需要傳參數(shù)時,args是一個元組,如果只有一個參數(shù),一定后面要加一個,符號。不能只有一個參數(shù)否則線程會報創(chuàng)建參數(shù)錯誤。threading.Thread(target=fuc,args=(arg,))

python之多線程

進程的概念:以一個整體的形式暴露給操作系統(tǒng)管理,里面包含各種資源的調(diào)用。 對各種資源管理的集合就可以稱為進程。

線程的概念:是操作系統(tǒng)能夠進行運算調(diào)度的最小單位。本質(zhì)上就是一串指令的集合。

進程和線程的區(qū)別:

1、線程共享內(nèi)存空間,進程有獨立的內(nèi)存空間。

2、線程啟動速度快,進程啟動速度慢。注意:二者的運行速度是無法比較的。

3、線程是執(zhí)行的指令集,進程是資源的集合

4、兩個子進程之間數(shù)據(jù)不共享,完全獨立。同一個進程下的線程共享同一份數(shù)據(jù)。

5、創(chuàng)建新的線程很簡單,創(chuàng)建新的進程需要對他的父進程進行一次克隆。

6、一個線程可以操作(控制)同一進程里的其他線程,但是進程只能操作子進程

7、同一個進程的線程可以直接交流,兩個進程想要通信,必須通過一個中間代理來實現(xiàn)。

8、對于線程的修改,可能會影響到其他線程的行為。但是對于父進程的修改不會影響到子進程。

第一個程序,使用循環(huán)來創(chuàng)建線程,但是這個程序中一共有51個線程,我們創(chuàng)建了50個線程,但是還有一個程序本身的線程,是主線程。這51個線程是并行的。注意:這個程序中是主線程啟動了子線程。

相比上個程序,這個程序多了一步計算時間,但是我們觀察結(jié)果會發(fā)現(xiàn),程序顯示的執(zhí)行時間只有0.007秒,這是因為最后一個print函數(shù)它存在于主線程,而整個程序主線程和所有子線程是并行的,那么可想而知,在子線程還沒有執(zhí)行完畢的時候print函數(shù)就已經(jīng)執(zhí)行了,總的來說,這個時間只是執(zhí)行了一個線程也就是主線程所用的時間。

接下來這個程序,吸取了上面這個程序的缺點,創(chuàng)建了一個列表,把所有的線程實例都存進去,然后使用一個for循環(huán)依次對線程實例調(diào)用join方法,這樣就可以使得主線程等待所創(chuàng)建的所有子線程執(zhí)行完畢才能往下走。 注意實驗結(jié)果:和兩個線程的結(jié)果都是兩秒多一點

注意觀察實驗結(jié)果,并沒有執(zhí)行打印task has done,并且程序執(zhí)行時間極其短。

這是因為在主線程啟動子線程前把子線程設(shè)置為守護線程。

只要主線程執(zhí)行完畢,不管子線程是否執(zhí)行完畢,就結(jié)束。但是會等待非守護線程執(zhí)行完畢

主線程退出,守護線程全部強制退出。皇帝死了,仆人也跟著殉葬

應(yīng)用的場景 : socket-server

注意:gil只是為了減低程序開發(fā)復(fù)雜度。但是在2.幾的版本上,需要加用戶態(tài)的鎖(gil的缺陷)而在3點幾的版本上,加鎖不加鎖都一樣。

下面這個程序是一個典型的生產(chǎn)者消費者模型。

生產(chǎn)者消費者模型是經(jīng)典的在開發(fā)架構(gòu)中使用的模型

運維中的集群就是生產(chǎn)者消費者模型,生活中很多都是

那么,多線程的使用場景是什么?

python中的多線程實質(zhì)上是對上下文的不斷切換,可以說是假的多線程。而我們知道,io操作不占用cpu,計算占用cpu,那么python的多線程適合io操作密集的任務(wù),比如socket-server,那么cpu密集型的任務(wù),python怎么處理?python可以折中的利用計算機的多核:啟動八個進程,每個進程有一個線程。這樣就可以利用多進程解決多核問題。

名稱欄目:python線程函數(shù) python 多線程 函數(shù)
標題路徑:http://chinadenli.net/article8/doopeop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營銷推廣營銷型網(wǎng)站建設(shè)定制網(wǎng)站網(wǎng)站導(dǎo)航網(wǎng)站策劃網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計