日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多任务编程—多进程

發(fā)布時間:2023/12/2 编程问答 53 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多任务编程—多进程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

什么是多任務(wù)編程?

  多任務(wù)編程其實和計算機系統(tǒng)內(nèi)核有關(guān),通過程利用多個計算機內(nèi)核同時執(zhí)行程序,以此來提升程序執(zhí)行的效率。

  多任務(wù)編程其中包括,多進程、多線程和多協(xié)程,這三種多任務(wù)編程各有各的優(yōu)點和缺點,本章就來講一下進程。

首先,什么是進程?

  進程就是一次執(zhí)行的程序,最直接的例子就是我們常用的任務(wù)管理器,任務(wù)管理器,任務(wù)管理中每一個運行中的程序其實都叫進程。  

  在編程中進程是程序的一種動態(tài)過程的描述,進程在執(zhí)行過程中會占用我們計算機內(nèi)的資源,但是每個進程都有自己的生命周期(進程在系統(tǒng)內(nèi)核所存在的時間),生命周期結(jié)束后進程會自動銷毀。

每個進程都會有一個獨立的虛擬內(nèi)存(4g),使其在運行過程中獨立進行。

  

?  進程的在編程中的作用是為了處理程序并發(fā)的一種方式或者說是方法可能會更貼切一點,進程適用于同一程序每次都執(zhí)行不同的任務(wù),我們稱之為多進程,多進程中分為父進程和子進程。

  創(chuàng)建進程的方式一共有兩種:

  第一種:導(dǎo)入 import os 模塊 ,利用 os 模塊中的fork( )內(nèi)建函數(shù)來創(chuàng)建子進程,fork( )創(chuàng)建并不難,但是最值得注意的是fork( )這個函數(shù)返回值,這個函數(shù)相比于其他函數(shù)有些特殊,fork( )自身擁有三種返回值,分別是小于0,等于0 和大于0的pid(系統(tǒng)對進程的唯一編號)數(shù)字,這三種分對應(yīng)著不同的處理結(jié)果。

小于0 —【創(chuàng)建子進程失敗

等于0 —【創(chuàng)建子進程成功】

大于 0—【父進程】

  在創(chuàng)建過程中一般情況下都會給fork( )的返回值設(shè)定一個if判斷語句,以此來確認(rèn)子進程是否創(chuàng)建成功,至于這個返回值的判斷機制是完全由系統(tǒng)內(nèi)核經(jīng)過自動計算后所返回的,這個是機制是不可抗的。下面我們就來創(chuàng)建一個子進程實例,代碼如下:

import os


print('---------分割線-----------')

pid = os.fork()#開始創(chuàng)建子進程
print('fock返回的pid號',pid)

if pid < 0:
print('創(chuàng)建子進程失敗')

elif pid == 0:
print('創(chuàng)建子進程成功')

else:
print('這是父進程') #父進程會先執(zhí)行

運行結(jié)果:

?

?

  由此我們可以出所返回值,運行程序中分別生成了一個大于0和一個?等于0數(shù)字,說明子進程已經(jīng)創(chuàng)建成功,因此小于0的值并不會被生成出來。我們可以在已創(chuàng)建的子進程中可以添加自己所需要的內(nèi)容,讓每個程序都在一個子進程中獨立分開執(zhí)行,達(dá)到并發(fā)效果。那么在創(chuàng)建成功后子進程都會包含什么?

  子進程會復(fù)制父進程中所有的代碼,但是子進程不會執(zhí)行所復(fù)制的所有代碼段,它只會運行所創(chuàng)建的子進程代碼段,父進程的代碼段子進程并不會去運行。(紫色的部分代表分別要執(zhí)行的代碼段

  如下圖:

?

  如果多個進程在同時搶占計算機資源時應(yīng)該怎么辦,實際上會使計算機對所有進程進行一種快速切換的機制,a進程和b進程同時執(zhí)行的時候誰先誰后不可定,但是他們一定是交叉運行的。在運行a進程時計算機會把資源 分配給a去使用,但是這時候b進程突然運行,計算機就會把資源在分配給 b去運行,這個過程就是計算機內(nèi)部的資源分配機制。

  但是使用fork( )創(chuàng)建多個子進程就會非常麻煩,子進程中嵌套二級子進程以此類推,這樣不停的去使用if嵌套在結(jié)構(gòu)上是一種很不好的一種體驗,所以在python中有一個更加清晰簡潔的一種創(chuàng)建方式,使用multiprocessing模塊中的Process去創(chuàng)建多個子進程。

?

?

target=‘目標(biāo)函數(shù)'

agrs=(’參數(shù)',)#元組傳參

kwargs ={'key':‘value’}#字典傳參

name='命名'?

start( ) #啟動子進程

join( ) #子進程的回收

  它的代碼結(jié)構(gòu)非常的清晰,但是相對于fork( ) 它增加了兩個機制,一個是啟動函數(shù)strart( ) 和阻塞等待子進程回收機制 join( ),只有所有的子進程全部執(zhí)行完畢后才會回收,這兩個函數(shù)分別控制子進程的開始和結(jié)束,其中jion( )這個函數(shù)里面可以添加參數(shù)(秒),在輸入相應(yīng)的數(shù)字時會自動開始倒計時等待,如果在倒計時結(jié)束后join( )機制會執(zhí)行,但是這個時候join( )子進程并沒有結(jié)束,父進程檢測到?jīng)]有join阻塞也會執(zhí)行,這個時候子進程就變?yōu)榱斯聝哼M程,孤兒進程在執(zhí)行完畢后,會在系統(tǒng)中找一個繼父并結(jié)束,也就是說這個繼父收養(yǎng)了這個孤兒進程,使其能夠正常結(jié)束。

?進程的三態(tài)和五態(tài):

三態(tài)

就緒態(tài) : 進程具備運行條件,等待系統(tǒng)分配處理器運行
運行態(tài) : 進程占有cpu處于運行的狀態(tài)
等待態(tài) : 又稱為阻塞態(tài),睡眠態(tài),指進程暫時不具備運

五態(tài)

新建態(tài) : 創(chuàng)建一個進程,獲取資源,直接表現(xiàn)為運行一個程序,或者在程序中創(chuàng)建新的進程

終止態(tài) : 進程執(zhí)行結(jié)束,資源回收過程

  進程池:

  進程池:一次創(chuàng)建多個進程批量執(zhí)行多個任務(wù)的程序,頻繁大量的任務(wù)建議使用進程池  比如一個進程創(chuàng)建后每兩秒就銷毀,但是任務(wù)兩很大需要大量重復(fù)這個創(chuàng)建銷毀的過程,這種情況下就建議使用進程池去處理 ,打個比方,一輛車上需要搬運200個西瓜才能達(dá)到運送標(biāo)準(zhǔn),在搬運西瓜給貨車的同時有n個人一起去完成這個任務(wù),每次填裝的西瓜數(shù)量是n個,可以很快的就將這200個西瓜裝載完畢,大大的 節(jié)省了時間成本,所謂的進程池的執(zhí)行方式就是這個概念。

  進程池每次處理事件時不會像普通進程那樣每次處理完事件就會回收,進程池只有處理完所有的事件才會統(tǒng)一回收,再打個比方給大家:

我們創(chuàng)建了四個進程,事件需要執(zhí)行20次,那么這個進程池每次可以處理1-4這四次事件后并不會回收,等到需要再次處理5-8這四個進程時在開啟,隨后再次關(guān)閉,這違背了進程池設(shè)計的初衷,進程池內(nèi)只有執(zhí)行完這20次的所有事件后才會結(jié)束銷毀。

  創(chuàng)建進程池使用 Pool函數(shù),形式上和創(chuàng)建進程大同小異,首先需要創(chuàng)建一個事件函數(shù),準(zhǔn)備執(zhí)行,使用Pool(processes=n)來創(chuàng)建n個進程,等待事件的處理,進程池不需要使用start( ) 函數(shù)來啟動進程,進程池內(nèi)有它特有的處理事件的機制,因為在在進程池創(chuàng)建完成后進程就已經(jīng)是處在一個等待運行的狀態(tài)了,將事件放入后,進程會立即執(zhí)行所放入的事件。

  異步處理和同步處理。

  異步處理:apply_async( ) 第一個參數(shù)為所執(zhí)行的目標(biāo)函數(shù),第二個參數(shù)為實參,實參的傳遞方式可以選擇元祖?zhèn)鲄⒑妥值鋫鲄?#xff0c;在調(diào)用函數(shù)和傳遞參數(shù)時不需要通過target和args調(diào)用, 異步處理會搶占時間片,可以理解成異步處理是一種無序隨機運行。

  同步處理:apply( ) 同步處理的調(diào)用和傳遞實參的方式和異步處理相同,二者唯一的區(qū)別就是一個是有序運行,一種是無序運行。

  close( )

  進程池中的join( )同樣是等待進程回收,這個之前就已經(jīng)說過來了,就不在細(xì)說,我們重點來看一下這個close( ), close關(guān)閉并不是終止進程池運行,而是‘關(guān)閉’進程池使其不在接受其他新的事件元素 ,并不是所謂的終止運行。

  map函數(shù)?

  進程池中可以使用map函數(shù)對進程池中的數(shù)據(jù)進行處理,map函數(shù)我們在接觸高階函數(shù)的時候就已經(jīng)接觸過了,但是在這里還有一些小小的不同。

  以上代碼所示:在進程池中使用map處理元素 ,第一個參數(shù)為需要調(diào)用 的目標(biāo)函數(shù),第二個位置是一個迭代器,將迭代對象傳入事件進行處理,因為 l 這個跌迭對象擁有6個元素,但是我們的進程池只有三個進程(每處理一次讓他停一秒,方便我們觀察),所以每秒鐘只能處理三個元素,兩秒后處理完畢,最終將結(jié)果打印在終端上。

  注:如果在多進程中需要讓第一個子進程完全執(zhí)行完畢后,在執(zhí)行第二個子進程,以此類推,這樣的情況可以考慮使用進程所 Lock或Event去設(shè)置子進程的阻塞狀態(tài),改變執(zhí)行效果。

?

轉(zhuǎn)載于:https://www.cnblogs.com/Jimmy1995/p/9323177.html

總結(jié)

以上是生活随笔為你收集整理的多任务编程—多进程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。