python 多程式詳解

crystalnsd發表於2017-10-26

眾所周知,Python 因為GIL的存在,不能很好的利用cpu多核的優勢,所以當我們在處理CPU計算型的任務的時候,我們要應該使用多執行緒模組multiprocessing ,下面將深入multiprocessing 模組進行介紹

1 multiprocessing 模組的基本用法

示例:

# -*- coding: utf-8 -*-
"""
Created on Fri Oct 13 11:48:27 2017

@author: 80002419
"""

import multiprocessing
import time
from multiprocessing.dummy import Pool
#from multiprocessing import Pool

def cost(fun):
    def wrapper(*args,**kwargs):
        before = time.time()
        fun(*args,**kwargs)
        after = time.time()
        print('{} cust {} s'.format(fun.__name__,after - before))
    return wrapper

def fibs(n):
    if n == 1:
        return 0
    if n == 2:
        return 1
    if n > 2:
        return fibs(n-2) + fibs(n-1)

@cost
def nomultiprocess():
    fibs(34)
    fibs(34)
    fibs(34)

nomultiprocess()
jobs = []
@cost
def hasmultiprocess():
    for _ in range(3):
        p = multiprocessing.Process(target = fibs, args = (34,))
        p.start()
        jobs.append(p)
    for p in jobs:
        p.join()
hasmultiprocess()

執行結果:

nomultiprocess cust 4.98667788506 s
hasmultiprocess cust 1.74044203758 s

由執行結果可以看出,multiprocessing 模組成功的緩解了GIL 問題

2 程式池:

在日常開發中,我們會利用程式池來緩解的,程式重複關啟帶來的消耗,multiprocessing也對也程式池有了實現

#from multiprocessing.dummy import Pool #cost 14s
from multiprocessing import Pool #cost 4s
pool = Pool(3)
pool.map(fibs,[34] * 3) #這裡的map 方法與python 高階函式方法類似,只是這裡的map方法是在程式池多程式併發進行的
pool.close() # 關閉里程池
pool.join()# 等待多程式任務執行完成,再執行後面程式碼

在多執行緒中,
還有一模擬多程式api 的多執行緒池,multiprocessing.dummy.Pool,他api 跟 multiprocessing.Pool一樣,
但是後確是一個執行緒池的實現
所以在開發的中,程式碼可以寫成兩者相容的形式,我們可以根據兩都實現的時間長短來判斷使用多程式,還是多執行緒,

3 程式通訊

一般情況下,程式之間的通訊有以下幾種方式:

  • rpc
  • pipe
  • socket
  • 佇列
1,官方pipe通訊示例:

程式碼:

def fun1

相關文章