1. 程式人生 > >Python多進程池 multiprocessing Pool

Python多進程池 multiprocessing Pool

問題 hub gin lock test logger int 新的 eth

1. 背景

由於需要寫python程序, 定時、大量發送htttp請求,並對結果進行處理。
參考其他代碼有進程池,記錄一下。

2. 多進程 vs 多線程

  • c++程序中,單個模塊通常是單進程,會啟動幾十、上百個線程,充分發揮機器性能。(目前c++11有了std::thread編程多線程很方便,可以參考我之前的博客)
  • shell腳本中,都是多進程後臺執行。({ ...} &, 可以參考我之前的博客,實現shell並發處理任務)
  • python腳本有多線程和多進程。由於python全局解鎖鎖的GIL的存在,一般建議 CPU密集型應該采用多進程充分發揮多核優勢,I/O密集型可以采用多線程。

    盡管Python完全支持多線程編程, 但是解釋器的C語言實現部分在完全並行執行時並不是線程安全的。

    實際上,解釋器被一個全局解釋器鎖保護著,它確保任何時候都只有一個Python線程執行。
    GIL最大的問題就是Python的多線程程序並不能利用多核CPU的優勢 (比如一個使用了多個線程的計算密集型程序只會在一個單CPU上面運行)。

3. multiprocessing pool使用例子

對Pool對象調用join()方法會等待所有子進程執行完畢,調用join()之前必須先調用close(),讓其不再接受新的Process了

#coding=utf-8

import logging
import time
from multiprocessing import Pool

logging.basicConfig(level=logging.INFO, filename='logger.log')

class Point:
    def __init__(self, x = 0, y= 0):
        self.x = x
        self.y = y
    def __str__(self):
        return "(%d, %d)" % (self.x, self.y)

def fun1(point):
    point.x = point.x + 3
    point.y = point.y + 3
    time.sleep(1)
    return point

def fun2(x):
    time.sleep(1)
    logging.info(time.ctime() + ", fun2 input x:" + str(x))
    return x * x

if __name__ == '__main__':
    pool = Pool(4)

    #test1
    mylist = [x for x in range(10)]
    ret = pool.map(fun2, mylist)
    print ret

    #test2
    mydata = [Point(x, y) for x in range(3) for y in range(2)]
    res = pool.map(fun1, mydata)
    for i in res:
        print str(i)

    #end
    pool.close()    
    pool.join()
    print "end"

4. 參考

  • Python 多進程 multiprocessing.Pool類詳解
  • Python 多線程和多進程編程總結
  • Python的全局鎖問題

Python多進程池 multiprocessing Pool