Python中的多程序


multiprocessing 包支援生成程序。它指的是一個載入並執行新子程序的函式。為了讓子程序終止或繼續執行併發計算,則當前程序必須使用類似於 threading 模組的 API 等待。

簡介

當我們使用多程序時,首先建立 **程序** 物件。然後它呼叫 start() 方法。

示例程式碼

from multiprocessing import Process
   def display():
      print ('Hi !! I am Python')
      if __name__ == '__main__':
      p = Process(target=display)
      p.start()
      p.join()

在這個例子中,我們首先匯入 Process 類,然後用 display() 函式初始化 Process 物件。

然後使用 start() 方法啟動程序,然後使用 join() 方法完成程序。

我們還可以使用 args 關鍵字將引數傳遞給函式。

示例

from multiprocessing import Process
   def display(my_name):
   print ('Hi !!!' + " " + my_name)
   if __name__ == '__main__':
      p = Process(target=display, args=('Python',))
      p.start()
      p.join()

在這個例子中,我們建立了一個計算數字立方並列印所有結果到控制檯的程序。

示例程式碼

from multiprocessing import Process
   def cube(x):
      for x in my_numbers:
         print('%s cube is %s' % (x, x**3))
      if __name__ == '__main__':
         my_numbers = [3, 4, 5, 6, 7, 8]
         p = Process(target=cube, args=('x',))
         p.start()
p.join
print ("Done")

輸出

Done
3 cube is 27
4 cube is 64
5 cube is 125
6 cube is 216
7 cube is 343
8 cube is 512

我們也可以一次建立多個程序。

在這個例子中,我們首先建立一個名為 process1 的程序,該程序只計算一個數字的立方,同時第二個程序 process2 檢查該數字是偶數還是奇數。

示例

from multiprocessing import Process
def cube(x):
   for x in my_numbers:
   print('%s cube is %s' % (x, x**3))
def evenno(x):
   for x in my_numbers:
   if x % 2 == 0:
   print('%s is an even number ' % (x))
   if __name__ == '__main__':
      my_numbers = [3, 4, 5, 6, 7, 8]
      my_process1 = Process(target=cube, args=('x',))
      my_process2 = Process(target=evenno, args=('x',))
      my_process1.start()
      my_process2.start()
      my_process1.join()
   my_process2.join()
print ("Done")

輸出

3 cube is 27
4 cube is 64
5 cube is 125
6 cube is 216
7 cube is 343
8 cube is 512
4 is an even number
6 is an even number
8 is an even number
Done

程序間通訊

多程序支援管道和佇列,這兩種是程序間通訊的兩種型別。

管道

在多程序中,當我們想要程序間通訊時,可以使用 **管道**。

示例

from multiprocessing import Process, Pipe
   def myfunction(conn):
      conn.send(['hi!! I am Python'])
      conn.close()
      if __name__ == '__main__':
         parent_conn, child_conn = Pipe()
         p = Process(target=myfunction, args=(child_conn,))
         p.start()
      print (parent_conn.recv() )
p.join()

輸出

['hi !!! I am Python']

管道返回兩個連線物件,它們表示管道的兩個端點。每個連線物件都有兩個方法,一個是 send() 方法,另一個是 recv() 方法。

在這個例子中,我們首先建立一個程序,該程序列印訊息“hi!! I am Python”,然後共享資料。

佇列

當我們在程序之間傳遞資料時,我們可以使用 Queue 物件。

示例

import multiprocessing
   def evenno(numbers, q):
      for n in numbers:
      if n % 2 == 0:
      q.put(n)
      if __name__ == "__main__":
         q = multiprocessing.Queue()
         p = multiprocessing.Process(target=evenno, args=(range(10), q))
         p.start()
         p.join()
   while q:
print(q.get())

輸出

0
2
4
6
8

在這個例子中,我們首先建立一個函式,該函式檢查一個數字是否為偶數。如果數字是偶數,則將其插入佇列的末尾。然後我們建立一個佇列物件和一個程序物件,然後啟動程序。

最後檢查佇列是否為空。

當我們列印數字時,我們首先列印佇列前面的值,然後是下一個值,依此類推。

當我們希望一次只執行一個程序時,可以使用鎖。這意味著該時間阻止其他程序執行類似的程式碼。在程序完成後,鎖將被釋放。

使用鎖方法的示例

示例

from multiprocessing import Process, Lock
def dispmay_name(l, i):
l.acquire()
print ('Hi', i)
   l.release()
if __name__ == '__main__':
   my_lock = Lock()
   my_name = ['Aadrika', 'Adwaita', 'Sakya', 'Sanj']
for name in my_name:
Process(target=dispmay_name, args=(my_lock,name)).start()

輸出

Hi Aadrika
Hi Adwaita
Hi Sakya
Hi Sanj

日誌記錄

multiprocessing 模組還提供日誌記錄模組,以確保如果日誌記錄包不使用鎖函式,則程序之間的訊息在執行期間不會混合。

示例

import multiprocessing, logging
logger = multiprocessing.log_to_stderr()
logger.setLevel(logging.INFO)
logger.warning('Error has occurred')

在這個例子中,我們首先匯入 logging 和 multiprocessing 模組,然後使用 multiprocessing.log_to_stderr() 方法。它還呼叫 get_logger() 以及新增到 sys.stderr,最後我們設定日誌記錄器的級別並傳遞訊息。

更新於: 2020年6月26日

5K+ 瀏覽量

開啟你的 職業生涯

透過完成課程獲得認證

開始學習
廣告

© . All rights reserved.