1. 程式人生 > >Python多程序 multiprocessing 筆記

Python多程序 multiprocessing 筆記

簡介

Python多程序主要集中在multiprocessing模組中實現相關功能。如

  • 程序的建立(Process)
  • Pool的使用(Pool)
  • 多個程序之間的資料交換(Queue, Pipes)
  • 多個程序之間資料共享(Value, Array, Manager)
  • 多個程序之間的同步操作(Lock)

實現樣例

在Windows系統實現多程序樣例時,

if __name__ == "__main__":

是必要的,確保主模組可以由新的Python直譯器安全匯入,而不會引起意外的副作用。

Process

使用multiprocessing.Process可以建立一個新的程序,通過start()方法啟動程序。

最佳實踐是在start()之後執行join()方法,因為在Unix系統當一個程序結束但是沒有join,該程序會變成殭屍程序(a zombie)。

但是join()方法在程序使用Queue時則不需要新增,反而可能會因為join方法的新增順序問題導致死鎖。因為一個程序put資料到Queue中會等待資料被消費才會終止,如果存在資料未被消費則程序一直等待。

# Process 構造引數說明
class multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={})
    @param group
    @param target:
run()方法可呼叫的物件 @param name: 程序名稱 @param args: 目標呼叫物件的引數, 預設無引數呼叫 @param kwargs: 目標呼叫的關鍵字引數字典
# -*- coding:utf-8 -*-
# @author Marvin Yang
# Process示例

from multiprocessing import Process

def multi(x, y):
    print "%s multi %s = %s" % (x, y, x*y)
    return x * y

def process_demo():
p = Process(target=multi, args=(3, 4)) p.start() p.join() def multi_process_demo(): for x in range(0, 5): for y in range(1, 4): p = Process(target=multi, args=(x, y)) p.start() p.join() if __name__ == "__main__": # 單個程序 process_demo() # 多個程序 multi_process_demo()

Pool

程序池可建立多個程序供使用,且提供了多個不同的執行方法。如apply, apply_async, map, map_async等。

# -*- coding:utf-8 -*-
# @author Marvin Yang
# Pool實現樣例

from multiprocessing import Process, Pool, Queue

def x2(x):
    return x*x
    
def multi(x, y):
    print "%s multi %s = %s" % (x, y, x*y)
    return x * y
    
def pool_demo():
    """ map同內建函式map()類似,
    將目標呼叫物件作用於每一個可迭代引數上
    意味著如果目標呼叫物件包含多個引數則不適合用map方法
    """
    pool = Pool(processes=4)
    print(pool.map(x2, [random.randrange(0, 10), 45, 3, 4, 6]))

def pool_apply_demo():
    """ apply同內建apply()類似,
    可以有返回值
    一個apply使用Pool中的一個程序
    """
    pool = Pool(processes=4)
    r = pool.apply_async(x2, args=(3, ))
    s = pool.apply_async(multi, args=(4, 5))
    print(r.get())
    print(s.get())
    
if __name__ == "__main__":
    # pool demo
    pool_demo()
    pool_apply_demo()

Queue

通過Queue實現多個程序之間的資料交換。Pipes同樣也可以實現多個程序之間的資料交換,一個頭用來輸入,一個頭用來接收。

# -*- coding:utf-8 -*-
# @author Marvin Yang

from multiprocessing import Process, Pool, Queue
import time

def queue_put_demo(queue):
    """ 推送資料到Queue
    
    """
    for i in range(0, 10):
        print "input queue: %s" % i
        queue.put(["here is a queue demo", "queue", "%s" % i])
        #time.sleep(1)


def queue_get_demo(queue):
    """ 從Queue中獲取資料展示
    
    """
    count = 0
    while count < 10 or not queue.empty():
        if queue.empty():
            time.sleep(2)
        else:
            obj = queue.get()
            for item in obj:
                print item, len(item)
        count += 1


def queue_demo():
    """ 兩個程序,一個推送資料到佇列,一個從佇列中獲取資料展示
    
    """
    queue = Queue()
    put_p = Process(target=queue_put_demo, args=(queue, ))
    get_p = Process(target=queue_get_demo, args=(queue, ))
    put_p.start()
    get_p.start()


if __name__ == "__main__":
    queue_demo()

more

通過上述介紹簡單的多程序操作可以滿足日常的一些資料處理功能,更多的多程序的細節和功能還需要繼續學習。

參考文獻

python-2.7.14-docs-html -> module: multiprocessing