初學Python——進程

來源:互聯網
上載者:User

標籤:nat   col   reading   char   進程間   分享   manager   不能   ase   

什麼是進程?

  程式不能單獨執行,只有將程式裝載到記憶體中,系統為它分配資源才能運行,而這種執行的過程就叫做進程。進程是作業系統調度的最小單位。

  程式和進程的區別在於:程式是儲存在硬碟上指令的有序集合,是靜態;進程是程式的一次執行過程,屬於動態概念。

線程和進程的區別:

進程是資源的集合,進程要在CPU執行,必須要建立線程,至少要有一個線程在運行。

  1.線程共用建立它的進程的地址空間。進程的記憶體空間是獨立的。

  2.線程可以直接存取其進程的資料區段(不同線程共用同一個進程的資料),進程間不共用。

  3.線程可以與其他線程進行通訊,進程必須使用處理序間通訊(中間代理)與同級進程進行通訊。

  4.新的線程很容易建立,新的進程需要父進複製。

  5.線程可以直接操作和控制同一進程內的其它線程,而進程只能操作子進程。

  6.對主線程的修改可能會影響到其它線程的行為。對父進程的修改不會影響子進程(不刪除父進程的前提下)。

 Python多進程的使用

Process 類用來描述一個進程對象。建立子進程的時候,只需要傳入一個執行函數和函數的參數即可完成 Process 樣本的建立。

  star() 方法啟動進程。

  join() 方法實現進程間的同步,等待所有進程退出。

  close() 用來阻止多餘的進程湧入進程池 Pool 造成進程阻塞。

multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

  target 是函數名字,需要調用的函數

  args 函數需要的參數,以 元組 的形式傳入

 multiprocessing模組的使用跟線程類似

import multiprocessingimport threadingimport timedef t_run():    print("線程號",threading.get_ident()) # 線程iddef run(name):    time.sleep(1)    print(‘hello‘, name)    t = threading.Thread(target=t_run)    t.start()if __name__ == ‘__main__‘:    for i in range(10):        p = multiprocessing.Process(target=run, args=(i,))        p.start()
multiprocessing

所有的進程都是由父進程啟動的,所以發現此程式的父進程ID正是PyCharm。

每個進程都是相互獨立的,存在於不同的記憶體位址。

處理序間通訊
  • 首先聲明一點,這裡所說的處理序間通訊指的是父子進程之間的通訊機制。如果兩個進程間沒有關係,這裡的機制是無法奏效的。
  • 通訊方式有:進程隊列Queue、管道通訊Pipe、共用資料Manger
1.進程隊列Queue

  進程隊列直接使用multiprocessing模組的Queue類,不同於線程隊列的queue模組。

import multiprocessingdef f(q):    q.put([42, None, ‘hello‘])    q.put(30)if __name__ == ‘__main__‘:    q = multiprocessing.Queue()    p = multiprocessing.Process(target=f, args=(q,)) # 將隊列copy一份傳給子進程    p.start()    print(q.get())  # 在父進程中取出隊列中資料    print(type(q.get()))    p.join()
進程隊列2.管道Pipe

  兩個進程在管道兩邊收發資料。

import multiprocessing‘‘‘Pipe管道執行個體,兩個進程在管道兩邊收發資料‘‘‘def f(conn):    conn.send([42, None, ‘hello‘])  # 發送資料    print("child_conn接收:",conn.recv())   # 接收資料    conn.close()def s(conn):    conn.send("你好,紫禁城")  # 發送資料    print("parent_conn接收:",conn.recv())   # 接收資料    conn.close()if __name__ == ‘__main__‘:    parent_conn, child_conn = multiprocessing.Pipe() # 管道執行個體,串連著兩個進程    p = multiprocessing.Process(target=f, args=(child_conn,))    p2 = multiprocessing.Process(target=s,args=(parent_conn,))    p.start()    p2.start()    #print(parent_conn.recv())          # 父進程接收管線的資料    #parent_conn.send("你好,紫禁城")   # 父進程發送資料    p.join()    p2.join()
Pipe3.進程間共用資料Manger

  使用Manger()可以建立共用的資料,包括列表,字典,元組等多種類型。

from multiprocessing import Process, Manager  def f(d, l):    d[1] = ‘1‘    d[‘2‘] = 2    d[0.25] = None    l.append(1)    print(l)  if __name__ == ‘__main__‘:    with Manager() as manager:        d = manager.dict()          l = manager.list(range(5))        p_list = []        for i in range(10):            p = Process(target=f, args=(d, l))            p.start()            p_list.append(p)        for res in p_list:            res.join()          print(d)        print(l)
MangerLock

  螢幕鎖,防止一個進程未列印完畢,另一個進程插入

def f(l,i):    l.acquire()    print("hello",i)    l.release()if __name__ == ‘__main__‘:    l=Lock()    for i in range(10):        Process(target=f,args=(l,i)).start()
lock進程池

在利用Python進行系統管理的時候,特別是同時操作多個檔案目錄,或者遠端控制多台主機,並行操作可以節約大量的時間。當被操作對象數目不大時,可以直接利用multiprocessing中的Process動態成生多個進程,10幾個還好,但如果是上百個,上千個目標,手動的去限制進程數量卻又太過繁瑣,這時候進程池Pool發揮作用的時候就到了。

Pool可以提供指定數量的進程,供使用者調用,當有新的請求提交到pool中時,如果池還沒有滿,那麼就會建立一個新的進程用來執行該請求;但如果池中的進程數已經達到規定最大值,那麼該請求就會等待,直到池中有進程結束,才會建立新的進程來它。這裡有一個簡單的例子:

from multiprocessing import Process, Poolimport time, os  def Foo(i):    time.sleep(5)    print(‘in process[Foo]‘, os.getpid())    return i + 100  def Bar(arg):  # 父進程去執行,而不是子進程調用    print(‘-->exec done:‘, arg)    print(‘in process[Bar]‘, os.getpid())  if __name__ == ‘__main__‘:    pool = Pool(5)  # 允許進程池裡同時放入5個進程 其他多餘的進程處於掛起狀態     for i in range(10):        pool.apply_async(func=Foo, args=(i,), callback=Bar)          # pool.apply(func=Foo, args=(i,))       print(‘end:‘, os.getpid())    pool.close()  # close() 必須在join()前被調用    pool.join()   # 進程池中進程執行完畢後再關閉,如果注釋,那麼程式直接關閉。
進程池
  • pool.apply_async()用來向進程池提交目標請求。
  • pool.join()是用來等待進程池中的worker進程執行完畢,防止主進程在worker進程結束前結束。但pool.join()必須使用在pool.close()或者pool.terminate()之後。
  • close()terminate()的區別在於close()會等待池中的worker進程執行結束再關閉pool,而terminate()則是直接關閉。
  • result.successful()表示整個調用執行的狀態,如果還有worker沒有執行完,則會拋出AssertionError異常。    
  • 利用multiprocessing下的Pool可以很方便的同時自動處理幾百或者上千個並行操作,指令碼的複雜性也大大降低.

 

初學Python——進程

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.