最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python并發(fā):多線程與多進(jìn)程的詳解

 更新時(shí)間:2019年01月24日 11:42:50   作者:Python新世界  
今天小編就為大家分享一篇關(guān)于Python并發(fā):多線程與多進(jìn)程的詳解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧

本篇概要

1.線程與多線程

2.進(jìn)程與多進(jìn)程

3.多線程并發(fā)下載圖片

4.多進(jìn)程并發(fā)提高數(shù)字運(yùn)算

關(guān)于并發(fā)

在計(jì)算機(jī)編程領(lǐng)域,并發(fā)編程是一個(gè)很常見(jiàn)的名詞和功能了,其實(shí)并發(fā)這個(gè)理念,最初是源于鐵路和電報(bào)的早期工作。比如在同一個(gè)鐵路系統(tǒng)上如何安排多列火車,保證每列火車的運(yùn)行都不會(huì)發(fā)生沖突。

后來(lái)在20世紀(jì)60年代,學(xué)術(shù)界對(duì)計(jì)算機(jī)的并行計(jì)算開(kāi)始進(jìn)行研究,再后來(lái),操作系統(tǒng)能夠進(jìn)行并發(fā)的處理任務(wù),編程語(yǔ)言能夠?yàn)槌绦驅(qū)崿F(xiàn)并發(fā)的功能。

線程與多線程

什么是線程

一個(gè)線程可以看成是一個(gè)有序的指令流(完成特定任務(wù)的指令),并且可以通過(guò)操作系統(tǒng)來(lái)調(diào)度這些指令流。

線程通常位于進(jìn)程程里面,由一個(gè)程序計(jì)數(shù)器、一個(gè)堆棧和一組寄存器以及一個(gè)標(biāo)識(shí)符組成。這些線程是處理器可以分配時(shí)間的最小執(zhí)行單元。

線程之間是可以共享內(nèi)存并且互相通信的。但是當(dāng)兩個(gè)線程之間開(kāi)始共享內(nèi)存,就無(wú)法保證線程執(zhí)行的順序,這可能導(dǎo)致程序錯(cuò)誤,或者產(chǎn)生錯(cuò)誤的結(jié)果。這個(gè)問(wèn)題我們?nèi)蘸髸?huì)專門提及。

下面這個(gè)圖片展示了多個(gè)線程在多個(gè)CPU中的存在方式:

線程的類型

在一個(gè)典型的操作系統(tǒng)里面,一般會(huì)有兩種類型的線程:

1.用戶級(jí)線程:我們能夠創(chuàng)建、運(yùn)行的線程;

2.內(nèi)核級(jí)線程:操作系統(tǒng)運(yùn)行的低級(jí)別線程;

Python工作在用戶級(jí)線程上,我們介紹的內(nèi)容也主要是在用戶級(jí)的線程上運(yùn)行的。

什么是多線程

現(xiàn)在的CPU基本上都是多線程的CPU,比如我們隨意從京東上找一個(gè)Inter的酷睿i5處理器,看看它的產(chǎn)品規(guī)格:

這些CPU能夠同時(shí)運(yùn)行多個(gè)線程來(lái)處理任務(wù),其實(shí)從本質(zhì)上來(lái)說(shuō),這些CPU是利用一個(gè)能夠在多個(gè)線程之間快速切換的單個(gè)內(nèi)核來(lái)完成多線程的運(yùn)行的,切換線程的速度足夠快,所以我們并不會(huì)感覺(jué)到。但實(shí)質(zhì)上,它們并不是同時(shí)運(yùn)行的。

為了形象的理解多線程,我們來(lái)回憶一個(gè)場(chǎng)景。

在大學(xué)時(shí)代,期末的時(shí)候,有些科目的老師為了不為難大家,把考試設(shè)為開(kāi)卷考試,不知道大家面對(duì)開(kāi)卷考試的時(shí)候,做題的順序是怎樣的?

在單線程的工作模式下,我們從選擇題到填空題到簡(jiǎn)答題再到分析題,一個(gè)一個(gè)按順序的寫。

遇到一個(gè)特別難的題目,我們就要翻書翻資料了,當(dāng)然既然是開(kāi)卷考試,有些題目的答案就不可能直接出現(xiàn)在教科書中,那么我們就要花費(fèi)更多的時(shí)間來(lái)找答案,直到考試結(jié)束,因?yàn)槟硞€(gè)難題耗費(fèi)的翻書時(shí)間太多,導(dǎo)致后面一些簡(jiǎn)單的題目也沒(méi)用做,嗯,開(kāi)卷都寫不完試卷,掛科名額就給你了。

而在多線程的工作模式下,我們也是按順序?qū)?,但是遇到難題時(shí),我們會(huì)稍微從書中找找答案,如果沒(méi)找到,就先做下面的題目,把會(huì)做的題目做好,做好了容易的題目,再回到那個(gè)難題上,仔細(xì)從書中的蛛絲馬跡中找答案。

在這個(gè)例子里面,我們只是一個(gè)人來(lái)完成,如果想要更快地完成考試,就得跟其他同學(xué)通力合作和分工了。

讓我們看看線程的一些優(yōu)點(diǎn):

1.多線程能夠有效提升I/O阻塞型程序的效率;

2.與進(jìn)程相比,占用的系統(tǒng)資源少;

3.線程間能夠共享資源,方便進(jìn)行通信;

線程還有一些缺點(diǎn):

1.Python中有全局解釋器鎖(GIL)的限制;

2.雖然線程之間能夠進(jìn)行通信,但是容易導(dǎo)致程序結(jié)果出錯(cuò),使用的時(shí)候必須小心;

3.在多線程之間切換的計(jì)算代價(jià)高,會(huì)導(dǎo)致程序的整體性能下降。

進(jìn)程與多進(jìn)程

進(jìn)程在本質(zhì)上與線程非常相似,進(jìn)程幾乎可以完成線程能夠完成的任何事情。

按照上面開(kāi)卷考試的例子,如果我們和室友組成一個(gè)小團(tuán)伙,那么我們就有四個(gè)CPU(4個(gè)人),四個(gè)人分別寫和找不同的答案,這樣考試的效率會(huì)提高很多。

一個(gè)進(jìn)程里面,包含一個(gè)主線程,還可以生成很多子線程,每個(gè)線程都包含自己的寄存器組合堆棧。如果有需要的話,可以將它們組成多線程。

下面是單線程單進(jìn)程和多線程單進(jìn)程的示例:

進(jìn)程的特性

一個(gè)進(jìn)程通常包含以下的內(nèi)容:

1.進(jìn)程ID,進(jìn)程組ID,用戶ID,組ID

2.環(huán)境

3.工作目錄

4.程序指令

5.寄存器

6.堆棧

7.文件描述

8.進(jìn)程間通信工具

9.等等……

進(jìn)程有以下優(yōu)點(diǎn):

1.更好地利用多核處理器;

2.在處理CPU密集型任務(wù)時(shí)比多線程要好;

3.可以通過(guò)多進(jìn)程來(lái)避免全局解釋器鎖(GIL)的局限;

4.崩潰的進(jìn)程不會(huì)導(dǎo)致整個(gè)程序的崩潰;

同時(shí),還有以下缺點(diǎn):

1.進(jìn)程之間沒(méi)有共享資源;

2.進(jìn)程需要消耗更多的內(nèi)存;

多進(jìn)程

在Python中我們可以使用多線程或者多進(jìn)程的方式來(lái)運(yùn)行我們的代碼以改進(jìn)傳統(tǒng)的單線程方式的性能。

在單核的CPU上可以使用多線程提高處理能力,但是在現(xiàn)在的計(jì)算機(jī)CPU中,多核處理器早已普及,為了有效的利用機(jī)器的資源,我們有必要使用多進(jìn)程來(lái)發(fā)揮機(jī)器的價(jià)值。

一個(gè)CPU內(nèi)核將任務(wù)分配給其他CPU:

通過(guò)Python的進(jìn)程處理模塊multiprocessing,我們可以有效的利用機(jī)器上所有的處理器,這有助于我們?cè)谔幚鞢PU密集型任務(wù)時(shí)獲得更高的性能。

使用multiprocessing模塊,查看我們機(jī)器上的CPU核心數(shù)量:

結(jié)果返回一個(gè)數(shù)字,為CPU核心數(shù)。

多進(jìn)程不僅能夠提高我們的計(jì)算機(jī)的利用率,還能夠避免全局解釋器鎖的限制,一個(gè)潛在的缺點(diǎn)是多進(jìn)程間不能進(jìn)行共享和通信(可以通過(guò)其他手段實(shí)現(xiàn)),但是這個(gè)缺點(diǎn)同時(shí)也使多進(jìn)程更加容易使用和避免出現(xiàn)崩潰。

Python的局限性

在文章的前面,我們談到了在Python中存在的全局解釋器鎖GIL的局限性。那GIL到底是個(gè)什么東西?

GIL本質(zhì)上是一個(gè)互斥鎖,它可以防止多個(gè)線程同時(shí)執(zhí)行Python代碼。 它是一個(gè)只能由一個(gè)線程保持的鎖,如果你想要一個(gè)線程去執(zhí)行代碼,那么在它執(zhí)行代碼之前,首先必須獲得這個(gè)鎖。 這樣做的一個(gè)好處是,當(dāng)它被鎖定的時(shí)候,沒(méi)有別的進(jìn)程可以同時(shí)運(yùn)行代碼,一定程度上避免了線程間的沖突:

上面這個(gè)圖說(shuō)明了多個(gè)線程如何被GIL阻塞。每個(gè)線程必須等待獲取到GIL才能進(jìn)行下一步的運(yùn)行,然后再釋放GIL。線程之間使用隨機(jī)循環(huán)的方式,所以并不能控制和保證哪個(gè)線程會(huì)先得到GIL。

這樣的設(shè)計(jì)也是很多人詬病Python的地方。但是,這個(gè)設(shè)計(jì)確實(shí)是保證的多線程之間的內(nèi)存安全。

現(xiàn)在我們已經(jīng)了解了線程和進(jìn)程,以及Python的一些限制,現(xiàn)在是時(shí)候了解一下我們?nèi)绾卧趹?yīng)用程序中使用多線程多進(jìn)程,以提高程序的速度。

并發(fā)文件下載

毫無(wú)疑問(wèn)的,展現(xiàn)多線程優(yōu)點(diǎn)的一個(gè)例子就是使用多線程來(lái)下載多個(gè)圖片或者文件,由于I/O的阻塞性質(zhì),下載任務(wù)可能是多線程最佳的運(yùn)用場(chǎng)景了。

http://tool.bitefu.net/jiari/data/2017.txt是一個(gè)提供2017年所有節(jié)假日的文本文件:

我們?cè)L問(wèn)10次,獲得10次文本文件,然后保存在本地。

先看看一個(gè)普通的爬?。?/strong>

我們引入了模塊urllib.request,然后創(chuàng)建了一個(gè)函數(shù)downloadImage()用于下載文件,創(chuàng)建了一個(gè)函數(shù)main()用于對(duì)下載函數(shù)進(jìn)行遍歷20次。

耗時(shí)4秒多。

下面看看使用多線程的:

程序的前部分大同小異,后面我們創(chuàng)建了一個(gè)threads列表,,然后遍歷10次,創(chuàng)建一個(gè)新的線程對(duì)象,將其添加到threads列表中,然后啟動(dòng)該線程。

最后,我們通過(guò)遍歷我們的threads列表來(lái)調(diào)用我們的線程,然后調(diào)用join()方法在每個(gè)線程上,這確保我們?cè)谙螺d完文件之前,不會(huì)執(zhí)行剩下的代碼。

運(yùn)行代碼,可以發(fā)現(xiàn)程序幾乎同時(shí)啟動(dòng)了10個(gè)下載任務(wù),然后在圖片下載完成后,再打印出來(lái)。

耗時(shí)0.1秒,效率提高很多。

但是需要注意的是,在網(wǎng)絡(luò)中進(jìn)行文件IO,還需要考慮網(wǎng)絡(luò)狀況和自身機(jī)器的影響,不同的網(wǎng)絡(luò)狀況下,完成的效率也不一樣。

并發(fā)數(shù)字運(yùn)算

I/O密集型的任務(wù)適合于多線程,而CPU密集型的任務(wù)則適合用多進(jìn)程。

在下面的例子里,我們將找出100萬(wàn)個(gè)20000到100000000之間隨機(jī)數(shù)的質(zhì)數(shù)。

順序運(yùn)算:

耗時(shí)18秒。

多進(jìn)程運(yùn)算:

耗時(shí)11秒。

我們分別按順序循環(huán)100萬(wàn)遍和使用多進(jìn)程的進(jìn)程池循環(huán)100萬(wàn)次,多進(jìn)程模式下速度提升了近7秒。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接

相關(guān)文章

  • Python中實(shí)現(xiàn)從目錄中過(guò)濾出指定文件類型的文件

    Python中實(shí)現(xiàn)從目錄中過(guò)濾出指定文件類型的文件

    這篇文章主要介紹了Python中實(shí)現(xiàn)從目錄中過(guò)濾出指定文件類型的文件,本文是一篇學(xué)筆記,實(shí)例相對(duì)簡(jiǎn)單,需要的朋友可以參考下
    2015-02-02
  • WxPython實(shí)現(xiàn)無(wú)邊框界面

    WxPython實(shí)現(xiàn)無(wú)邊框界面

    這篇文章主要為大家詳細(xì)介紹了WxPython實(shí)現(xiàn)無(wú)邊框界面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • python編程冒泡排序法實(shí)現(xiàn)動(dòng)圖排序示例解析

    python編程冒泡排序法實(shí)現(xiàn)動(dòng)圖排序示例解析

    這篇文章主要介紹了python編程中如何使用冒泡排序法實(shí)現(xiàn)動(dòng)圖排序的示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-10-10
  • Python自定義聚合函數(shù)merge與transform區(qū)別詳解

    Python自定義聚合函數(shù)merge與transform區(qū)別詳解

    這篇文章主要介紹了Python自定義聚合函數(shù)merge與transform區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • python pip配置國(guó)內(nèi)鏡像源的方法(永久和臨時(shí))

    python pip配置國(guó)內(nèi)鏡像源的方法(永久和臨時(shí))

    在使用 pip 安裝 Python 模塊時(shí),默認(rèn)的國(guó)外鏡像源可能會(huì)導(dǎo)致下載速度緩慢甚至超時(shí),為了解決這個(gè)問(wèn)題,可以使用國(guó)內(nèi)的鏡像源來(lái)加速下載,以下是常用的國(guó)內(nèi)鏡像源以及臨時(shí)和永久的配置方法,需要的朋友可以參考下
    2025-04-04
  • Python 如何讓特征值滯后一行

    Python 如何讓特征值滯后一行

    這篇文章主要介紹了Python 如何讓特征值滯后一行的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • keras實(shí)現(xiàn)圖像預(yù)處理并生成一個(gè)generator的案例

    keras實(shí)現(xiàn)圖像預(yù)處理并生成一個(gè)generator的案例

    這篇文章主要介紹了keras實(shí)現(xiàn)圖像預(yù)處理并生成一個(gè)generator的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-06-06
  • django框架之cookie/session的使用示例(小結(jié))

    django框架之cookie/session的使用示例(小結(jié))

    這篇文章主要介紹了django框架之cookie/session的使用示例(小結(jié)),詳細(xì)的介紹了cookie和session技術(shù)的接口獲取等問(wèn)題,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • python中的post請(qǐng)求解讀

    python中的post請(qǐng)求解讀

    文章介紹了Python中POST請(qǐng)求的4種編碼方式:application/x-www-form-urlencoded、multipart/form-data、application/json和text/xml,通過(guò)代碼示例和工具使用,展示了如何發(fā)送和處理這些請(qǐng)求
    2024-11-11
  • python修改注冊(cè)表終止360進(jìn)程實(shí)例

    python修改注冊(cè)表終止360進(jìn)程實(shí)例

    這篇文章主要介紹了python修改注冊(cè)表終止360進(jìn)程實(shí)例,是非常實(shí)用的進(jìn)程操作技巧,需要的朋友可以參考下
    2014-10-10

最新評(píng)論

万州区| 扬中市| 桐柏县| 桓仁| 临安市| 黔江区| 西充县| 凤庆县| 隆德县| 平山县| 嘉义市| 华亭县| 旺苍县| 新沂市| 河北区| 玉龙| 当雄县| 盐边县| 班玛县| 海原县| 柘城县| 香港 | 冷水江市| 迁安市| 白城市| 南靖县| 芦溪县| 建平县| 淳化县| 武强县| 澄城县| 衡南县| 泌阳县| 宣恩县| 芜湖县| 自治县| 惠来县| 建平县| 高州市| 政和县| 肥西县|