亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

在這個(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è)普通的爬取:

我們引入了模塊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變量的賦值、淺拷貝和深拷貝詳解

    Python變量的賦值、淺拷貝和深拷貝詳解

    這篇文章主要介紹了Python變量的賦值、淺拷貝和深拷貝詳解,python中為聲明一個(gè)變量有三種方法:賦值、淺拷貝、深拷貝,相信每個(gè)pythoner或多或少都知道他們之間的區(qū)別,但在某些點(diǎn)上,還是會(huì)踩坑,這篇文章記錄下所有關(guān)于這三者區(qū)別的疑問(wèn),需要的朋友可以參考下
    2023-11-11
  • Python入門變量的定義及類型理解

    Python入門變量的定義及類型理解

    本文適合編程語(yǔ)言零基礎(chǔ)的初學(xué)者,有打算轉(zhuǎn)行學(xué)習(xí)python的可以添加關(guān)注,后續(xù)小編將會(huì)把自己轉(zhuǎn)行學(xué)pyhton語(yǔ)言以來(lái)的所有筆記,和工作中總結(jié)的一些開(kāi)發(fā)經(jīng)驗(yàn)分享給大家
    2021-09-09
  • Python源碼學(xué)習(xí)之PyType_Type和PyBaseObject_Type詳解

    Python源碼學(xué)習(xí)之PyType_Type和PyBaseObject_Type詳解

    今天給大家?guī)?lái)的是關(guān)于Python源碼的相關(guān)知識(shí)學(xué)習(xí),文章圍繞著PyType_Type和PyBaseObject_Type展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • 學(xué)習(xí)Python需要哪些工具

    學(xué)習(xí)Python需要哪些工具

    這篇文章主要介紹了學(xué)習(xí)Python需要哪些工具,幫助大家開(kāi)始學(xué)習(xí)python編程,感興趣的朋友可以了解下
    2020-09-09
  • python多線程共享變量的使用和效率方法

    python多線程共享變量的使用和效率方法

    今天小編就為大家分享一篇python多線程共享變量的使用和效率方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-07-07
  • Python 解決相對(duì)路徑問(wèn)題:

    Python 解決相對(duì)路徑問(wèn)題:"No such file or directory"

    這篇文章主要介紹了Python 解決相對(duì)路徑問(wèn)題:"No such file or directory"具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-06-06
  • Python基礎(chǔ)數(shù)據(jù)類型tuple元組的概念與用法

    Python基礎(chǔ)數(shù)據(jù)類型tuple元組的概念與用法

    元組(tuple)是 Python 中另一個(gè)重要的序列結(jié)構(gòu),和列表類似,元組也是由一系列按特定順序排序的元素組成,這篇文章主要給大家介紹了關(guān)于Python基礎(chǔ)數(shù)據(jù)類型tuple元組的概念與使用方法,需要的朋友可以參考下
    2021-07-07
  • Python實(shí)現(xiàn)自動(dòng)整理表格的示例代碼

    Python實(shí)現(xiàn)自動(dòng)整理表格的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用Python實(shí)現(xiàn)自動(dòng)整理表格的功能,文中的示例代碼簡(jiǎn)潔易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-03-03
  • Python使用pyinstaller打包spec文件的方法詳解

    Python使用pyinstaller打包spec文件的方法詳解

    PyInstaller是一個(gè)用于將Python腳本打包成獨(dú)立的可執(zhí)行文件的工具,使用PyInstaller您可以將Python應(yīng)用程序轉(zhuǎn)換為可執(zhí)行文件,而無(wú)需用戶安裝Python解釋器或任何額外的庫(kù),這篇文章主要給大家介紹了關(guān)于Python使用pyinstaller打包spec文件的相關(guān)資料,需要的朋友可以參考下
    2024-08-08
  • python實(shí)現(xiàn)桌面氣泡提示功能

    python實(shí)現(xiàn)桌面氣泡提示功能

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)桌面氣泡提示功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07

最新評(píng)論