1. 程式人生 > >Python多程序之multiprocessing模組和程序池的實現

Python多程序之multiprocessing模組和程序池的實現

1、利用multiprocessing可以在主程序中建立子程序,提升效率,下面是multiprocessing建立程序的簡單例子,和多執行緒的使用非常相似
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ''' 程式碼是由主程序裡面的主執行緒從上到下執行的, 我們在主執行緒裡面又建立了兩個子程序,子進 程裡面也是子執行緒在幹活,這個子程序在主進 程裡面 ''' import
multiprocessing import time   def f0(a1):      time.sleep( 3 )     
print (a1) if __name__ = = '__main__' : #windows下必須加這句        t = multiprocessing.Process(target = f0,args = ( 12 ,))      t.daemon = True #將daemon設定為True,則主執行緒不比等待子程序,主執行緒結束則所有結束      t.start()        t2 = multiprocessing.Process(target = f0, args = ( 13 ,))      t2.daemon = True      t2.start()        print ( 'end' ) #預設情況下等待所有子程序結束,主程序才結束

  這裡的結果是直接打印出end就結束了,因為添加了t.daemon=True,join方法在程序裡面也可以用,跟執行緒的用法非常相似

2、程序之間預設是不能共用記憶體的

?
1 2 3 4 5 6 7 8 9 10 11 12 13 li = []   def f1(i):      li.append(i)      print ( '你好' ,li)   if __name__ = = '__main__' : #程序不能共用記憶體      for i in range ( 10 ):          p = Process(target = f1,args = (i,))          p.start()   '''每個程序都建立一個列表,然後新增一個因素進去,     每個程序之間的資料是不能共享的

  結果如圖

如果將程式碼改成threading,由於執行緒共用記憶體,所以結果是不一樣的,執行緒操作列表li之前,拿到的是前一個執行緒操作過的li列表,如圖

3、如果要程序之間處理同一個資料,可以運用陣列以及程序裡面的manager方法,下面程式碼介紹的是manager方法

 

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from multiprocessing import Process from multiprocessing import Manager       def f1(i,dic):      dic[i] = 200 + i      print (dic.values())   if __name__ = = '__main__' : #程序間預設不能共用記憶體      manager = Manager()      dic = manager. dict () #這是一個特殊的字典          for i in range ( 10 ):          p = Process(target = f1,args = (i,dic))          p.start()          p.join()

  這裡輸出如圖,表示每個程序都是操作這個字典,最後的輸出是有10個元素

如果是普通的字典,輸出如圖

 

4、multiprocessing模組裡面的程序池Pool的使用

(1)apply模組的使用,每個任務是排隊執行的

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from multiprocessing import Process,Pool from multiprocessing import Manager import time     def f1(a):      time.sleep( 2 )      print (a)   if __name__ = = '__main__' :      pool = Pool( 5 )      for i in range ( 5 ): #每次使用的時候會去程序池裡面申請一個程序          pool. apply (func = f1,args = (i,))          print ( '你好' ) #apply裡面是每個程序執行完畢了才執行下一個程序      pool.close() #執行完close後不會有新的程序加入到pool,join函式等待所有子程序結束      pool.join() #等待程序執行完畢,先呼叫close函式,否則會出錯

  執行結果如圖

(2)apply_async模組,會比apply模組多個回撥函式,同時是非同步的

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 from multiprocessing import Process,Pool from multiprocessing import Manager import time       def Foo(i):      time.sleep( 1 )      return i + 50   def Bar(arg):      print (arg)   if __name__ = = '__main__' :      pool = Pool( 5 )      for i in range ( 10 ):            '''apply是去簡單的去執行,而apply_async是執行完畢之後可以執行一          個回撥函式,起提示作用'''          pool.apply_async(func = Foo,args = (i,),callback = Bar) #是非同步的          print ( '你好' )      pool.close() #不執行close會報錯,因為join的原始碼裡面有個斷言會檢驗是否執行了該方法      pool.join() #等待所有子程序執行完畢,否則的話由於apply_async裡面daemon是設定為True的,主程序不會等子程序,所欲函式可能會來不及執行完畢就結束了 '''apply_async裡面,等函式Foo執行完畢,它的返回結果會被當做引數      傳給Bar'''

  結果如圖

這兩個方法的主要區別如圖

 

1、利用multiprocessing可以在主程序中建立子程序,提升效率,下面是multiprocessing建立程序的簡單例子,和多執行緒的使用非常相似
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ''' 程式碼是由主程序裡面的主執行緒從上到下執行的, 我們在主執行緒裡面又建立了兩個子程序,子進 程裡面也是子執行緒在幹活,這個子程序在主進 程裡面 ''' import multiprocessing import time   def f0(a1):      time.sleep( 3 )      print (a1) if __name__ = = '__main__' : #windows下必須加這句        t = multiprocessing.Process(target = f0,args = ( 12 ,))      t.daemon = True #將daemon設定為True,則主執行緒不比等待子程序,主執行緒結束則所有結束      t.start()        t2 = multiprocessing.Process(target = f0, args = ( 13 ,))      t2.daemon = True      t2.start()        print ( 'end' ) #預設情況下等待所有子程序結束,主程序才結束

  這裡的結果是直接打印出end就結束了,因為添加了t.daemon=True,join方法在程序裡面也可以用,跟執行緒的用法非常相似

2、程序之間預設是不能共用記憶體的

?
1 2 3 4 5 6 7 8 9 10 11 12 13 li = []   def f1(i):      li.append(i)      print ( '你好' ,li)   if __name__ = = '__main__' : #程序不能共用記憶體      for i in range ( 10 ):          p = Process(target = f1,args = (i,))          p.start()   '''每個程序都建立一個列表,然後新增一個因素進去,     每個程序之間的資料是不能共享的

  結果如圖

如果將程式碼改成threading,由於執行緒共用記憶體,所以結果是不一樣的,執行緒操作列表li之前,拿到的是前一個執行緒操作過的li列表,如圖

3、如果要程序之間處理同一個資料,可以運用陣列以及程序裡面的manager方法,下面程式碼介紹的是manager方法

 

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from multiprocessing import Process from multiprocessing import Manager       def f1(i,dic):      dic[i] = 200 + i      print (dic.values())   if __name__ = = '__main__' : #程序間預設不能共用記憶體      manager = Manager()      dic = manager. dict () #這是一個特殊的字典          for i in range ( 10 ):          p = Process(target = f1,args = (i,dic))          p.start()          p.join()

  這裡輸出如圖,表示每個程序都是操作這個字典,最後的輸出是有10個元素

如果是普通的字典,輸出如圖

 

4、multiprocessing模組裡面的程序池Pool的使用

(1)apply模組的使用,每個任務是排隊執行的

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from multiprocessing import Process,Pool from multiprocessing import Manager import time     def f1(a):      time.sleep( 2 )      print (a)   if __name__ = = '__main__' :      pool = Pool( 5 )      for i in range ( 5 ): #每次使用的時候會去程序池裡面申請一個程序          pool. apply (func = f1,args = (i,))          print ( '你好' ) #apply裡面是每個程序執行完畢了才執行下一個程序      pool.close() #執行完close後不會有新的程序加入到pool,join函式等待所有子程序結束      pool.join() #等待程序執行完畢,先呼叫close函式,否則會出錯

  執行結果如圖

(2)apply_async模組,會比apply模組多個回撥函式,同時是非同步的

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 from multiprocessing import Process,Pool from multiprocessing import Manager import time