<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一篇文章帶你解析Python進程

          共 5546字,需瀏覽 12分鐘

           ·

          2021-05-17 07:34

          點擊上方“Python爬蟲與數(shù)據(jù)挖掘”,進行關注

          回復“書籍”即可獲贈Python從入門到進階共10本電子書

          置酒長安道,同心與我違。

          前言

          進程,一個新鮮的字眼,可能有些人并不了解,它是系統(tǒng)某個運行程序的載體,這個程序可以有單個或者多個進程,一般來說,進程是通過系統(tǒng)CPU 內(nèi)核數(shù)來分配并設置的,我們可以來看下系統(tǒng)中的進程:

          可以看到,360瀏覽器是真的皮,這么多進程啊,當然可以這樣來十分清楚的看進程線程使用情況:

          通過任務管理器中的資源監(jiān)視器,是不是很厲害了,哈哈哈。講完了這些,再說說用法。


          1.基本用法

          進程能干什么,這是我們要深思熟慮的事情。我們都知道一個程序運行會創(chuàng)建進程,所以程序在創(chuàng)建這些進程的時候,為了讓它們更能有條不紊的工作,肯定也加入了線程。

          那么一條進程里面就會有多個線程協(xié)同作戰(zhàn),但是進程不可以創(chuàng)建過多,不然會消耗資源,除非你開發(fā)的是一個大型的系統(tǒng)。那么,我們現(xiàn)在就來創(chuàng)建一個進程吧。

          一、創(chuàng)建進程

          1.在創(chuàng)建進程之前,我們先導入進程的模塊,代碼如下:

          import multiprocess as mm.Process(target,args)

          其實這種寫法是不對的,就好比bs4中的BeautifulSoup,你想通過先導入bs4,然后再引入BeautifulSoup是行不通的,必須這樣:

          from multiprocessing import ProcessProcess(group, target, args, kwargs, name)group:用戶組target:調(diào)用函數(shù)args:參數(shù)元祖kwargs:參數(shù)字典name:子進程名稱

          可以看出進程和線程的用法基本差不多,只是名稱功能不同而已。而且還有很多其它優(yōu)秀的方法:

          # 返回當前進程存活的子進程的列表。調(diào)用該方法有“等待”已經(jīng)結(jié)束的進程的副作用。multiprocessing.active_children()
          # 返回系統(tǒng)的CPU數(shù)量。multiprocessing.cpu_count()

          2.創(chuàng)建單個進程

          由上述參數(shù)可知函數(shù)的返回值,基本與線程無差異化。

          #啟動進程,調(diào)用進程中的run()方法。start()
          #進程活動的方法run()
          #強制終止進程,不會進行任何清理操作。如果終止前創(chuàng)建了子進程,那么該子進程在其強制結(jié)束后變?yōu)榻┦M程;如果該進程還保存了一個鎖,那么也將不會被釋放,進而導致死鎖。terminate()
          #判斷某進程是否存活,存活返回True,否則False。is_alive()
          主線程等待子線程終止。timeout為可選擇超時時間;需要強調(diào)的是:p.join只能joinstart開啟的進程,而不能join住run開啟的進程。join([timeout])
          #設置進程為后臺守護進程;當該進程的父進程終止時,該進程也隨之終止,并且該進程不能創(chuàng)建子進程,設置該屬性必須在start()之前daemon
          #進程名稱。name
          #進程pid,在start后才能產(chǎn)生pid
          #子進程的退出代碼。如果進程尚未終止,這將是 None,負值-N表示子進程被信號N終止。exitcode
          #進程身份驗證,默認是os.urandom()隨機生成的字符串。校驗網(wǎng)進程連接是否正確authkey
          #系統(tǒng)對象的數(shù)字句柄,當進程結(jié)束時將變?yōu)?"ready" 。sentinel
          #殺進程kill()
          #關閉進程close()

          請注意:創(chuàng)建進程務必將它加入如下語句中:

          if __name__ == '__main__':

          這樣就實現(xiàn)了我們的一個關于進程的程序了。另外我們也可以通過繼承進程類來實現(xiàn):

          可以說我們每創(chuàng)建一個進程它就會有一個ID來標志它,下面情況:

          3.創(chuàng)建多個進程

          單個進程往往都是不夠用的,所有我們需要創(chuàng)建一個多進程,多進程創(chuàng)建方法也很簡單,加一層循環(huán)即可:

          這樣就輕松創(chuàng)建了多進程的任務,速度比以往就要更快了。


          4.進程池

          進程池的設計之初就是為了方便我們更有效的利用資源,避免浪費,如果任務量大就多個核一起幫忙,如果少就只開一兩個核,下面我們來看看實現(xiàn)過程:

          首先導入包:

          from multiprocessing import Poolimport multiprocessing as m

          進程池的安裝包為Pool,然后我們來看下它的CPU內(nèi)核數(shù):

          num=m.cpu_count()#CPU內(nèi)核數(shù)

          緊接著我們在來創(chuàng)建進程池:

          pool=multiprocessing.Pool(num)

          進程池中也有很多方法供我們使用:

          apply(funcargskwargs)                 同步執(zhí)行(串行) 阻塞
          apply_async(func,args,kwargs) 異步執(zhí)行(并行) 非阻塞
          terminate() 強制終止進程,不在處理未完成的任務。
          join() 主進程阻塞,等待子進程的退出。必須在closeterminate()之后使用
          close() 等待所有進程結(jié)束后,才關閉進程池
          map(func,iterable,chunksize=int) map函數(shù)的并行版本,保持阻塞直到獲得結(jié)果
          #返回一個可用于獲取結(jié)果的對象,回調(diào)函數(shù)應該立即執(zhí)行完成,否則會阻塞負責處理結(jié)果的線程map_async(func,iterable,chunksize,callback,error_callback)
          imap(func,iterable,chunksize) map的延遲執(zhí)行版本
          #和imap() 相同,只不過通過迭代器返回的結(jié)果是任意的imap_unordered(func,iterable,chunksize)
          #和 map() 類似,不過 iterable 中的每一項會被解包再作為函數(shù)參數(shù)。starmap(func,iterable,chunksize)

          為此我們可以創(chuàng)建同步和異步的程序,如果你對這對于爬蟲來說是很不錯的選擇,小點的爬蟲同步就好,大的爬蟲異步效果更佳,很多人不了解異步和同步,其實同步異步就是串行和并行的意思串行和并行簡單點說就是串聯(lián)和并聯(lián)。下面我們通過實例一起來看一下:

          一、串行

          二、并行

          可以看到,僅僅只是一個參數(shù)的變化而已,其它的都是大同小異,我們獲取到了當前進程的pid,然后把它打印出來了。


          5.鎖

          雖然異步編程多進程給我們帶來了便利,但是進程啟動后是不可控的,我們需要將它控制住,讓它干我們覺得有意義的事,這個時候我們需要給它加鎖,和線程一樣都是lock:

          首先導入進程鎖的模塊:

          from multiprocessing import Lock

          然后我們來創(chuàng)建一個關于鎖的程序:

          可以看到,加鎖的過程還是比較順利的,跟多線程一樣簡單,但是相對來說速度會慢一點。既然有Lock,那么勢必就有RLock了,在python 中,進程和線程的很多用法一致,鎖就是。我們可以把它改為RLock,下面便是可重入鎖,也就是可以遞歸:

          import timelock1=RLock()lock2=RLock()s=time.time()def jc(num):    lock1.acquire()    lock2.acquire()    print('start')    print(m.current_process().pid,'run----',str(num))    lock1.release()    lock2.release()    print('end')if __name__ == '__main__':    aa=[]    for y in range(12):        pp=Process(target=jc,args=(y,))        pp.start()        aa.append(pp)    for x in aa:        x.join()    e=time.time()    print(e-s)

          6.進程間通信

          一、Event

          進程間用于通信,方法和線程的一模一樣,這里舉個小栗子,不在詳細描述,不懂的可以看我上一篇關于線程的文章,我們今天要講的是其它的進程間通信方式,下面請看:

          import timee=Event()def main(num):    while True:        if num<5:            e.clear()   #清空信號標志            print('清空')        if num>=5:            e.wait(timeout=1) #等待信號標志為真            e.set()            print('啟動')                    if num==10:            e.wait(timeout=3)            e.clear()            print('退出')            break        num+=1        time.sleep(2)if __name__ == '__main__':    for y in range(10):        pp=Process(target=main,args=(y,))        pp.start()        pp.join()
          二、管道傳遞消息

          管道模塊初始化后返回兩個參數(shù),一個為發(fā)送者,一個為接收者,它有個參數(shù)可以設置模式為全雙工或者半雙工,全雙工收發(fā)一體,半雙工只收或者只發(fā),先了解下它的方法:

          p1,p2=m.Pipe(duplex=bool) #設置是否全雙工,返回兩個連接對象
          p1.send()  #發(fā)送p2.recv()  #接收p1.close()  #關閉連接p1.fileno() #返回連接使用的整數(shù)文件描述符p1.poll([timeout]) #如果連接上的數(shù)據(jù)可用,返回Truetimeout指定等待的最長時限。p2.recv_bytes([maxlength]) #接收最大字節(jié)數(shù)p1.send_bytes([maxlength]) #發(fā)送最大字節(jié)數(shù)#接收一條完整的字節(jié)消息,并把它保存在buffer對象中,offset指定緩沖區(qū)中放置消息處的字節(jié)位移.p2.recv_bytes_into(buffer [, offset])

          先收后發(fā),其實我們完全可以使用鎖來控制它的首發(fā),可以讓它一邊收一邊發(fā)。

          三、隊列

          隊列與其它不同的是它采取插入和刪除的方法,讓我們來看下:

          def fd(a):    for y in range(10):        a.put(y)  #插入數(shù)據(jù)        print('插入:',str(y))def df(b):    while True:        aa=b.get(True) #刪除數(shù)據(jù)        print('釋放:',str(aa))if __name__ == '__main__':    q=Queue()    ff=Process(target=fd,args=(q,))    dd=Process(target=df,args=(q,))    ff.start() #開始運行    dd.start()    dd.terminate() #關閉    ff.join()

          以上講的隊列主要用于多進程的隊列,還有一個進程池的隊列,它在Manager模塊中。


          7.信號量

          與線程中完全一樣,這里不在贅述,看下例:

          s=Semaphore(3)s.acquire()print(s.get_value())s.release()print(s.get_value())print(s.get_value())s.release()print(s.get_value())s.release()
          output:2334

          8.數(shù)據(jù)共享

          共享數(shù)據(jù)類型可以直接通過進程模塊來設置:

          數(shù)值型:m.Value()  數(shù)組性:m.Array()  字典型:m.dict()  列表型:m.list()

          也可以通過進程的Manager模塊來實現(xiàn):

          Manager().dict()Manager.list()

          下面我們就來舉例說明下吧:

          可以看到我們成功的將數(shù)據(jù)添加了進去,形成了數(shù)據(jù)的共享。


          2.總結(jié)

          通過對進程的描述,相信大家對進程此刻有了個深刻的感悟了吧,突然想起個事,就是大家學習時可能查資料會在網(wǎng)上搜索,那么我建議你專心看好我這篇好了,因為據(jù)我所知,那些都是錯的,而且更讓我納悶的是,明明代碼是錯的,放出來的執(zhí)行效果卻是對的,這讓我百思不得其解,哈哈哈。

          ------------------- End -------------------

          往期精彩文章推薦:

          歡迎大家點贊,留言,轉(zhuǎn)發(fā),轉(zhuǎn)載,感謝大家的相伴與支持

          想加入Python學習群請在后臺回復【入群

          萬水千山總是情,點個【在看】行不行

          /今日留言主題/

          隨便說一兩句吧~~

          瀏覽 41
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天堂资源视频 | 18禁 成人黄网站免费视频 | 免费日逼电影 | 亚洲,日韩,aⅴ在线欧美 | 日韩中文字幕无码中字字幕 |