python是解釋型的語言,而Python解譯器使用GIL(全域解 釋器鎖)來在內部禁止並存執行,正是這個GIL限制你在多核處理器上同一時間也只能執行一條位元組碼指令. python 3.0 裡面已經改進, 預設有了多處理器編程的庫了. Python2.XX暫時還不支援。
Parallel Python 這個庫,正是為次設計的, 而且它不僅可以多核處理器協同工作,還可以通過網路叢集運行。
http://www.parallelpython.com/
下面的中文介紹來自這裡:
1. 簡介
PP 是一個Python模組,提供了在SMP(多CPU或多核)和叢集(通過網路連接的多台電腦)上並存執行Python代碼的機制。輕量級,易於安裝,並 整合了其他軟體。PP也是一個用純Python代碼實現的跨平台,開放源碼模組。
2. 功能
* 在SMP和叢集上並存執行Python代碼
* 易於理解和實現的基於工作的並行機制,便於把穿行應用轉換成並行的
* 自動構造最佳配置(預設時背景工作處理序數量等同於系統處理器數量)
* 動態處理器分配(允許運行時改變工作處理器數量)
* 函數的工作緩衝(透明的緩衝機制確保後續調用降低負載)
* 動態負載平衡(任務被動態分配到各個處理器上)
* 基於SHA的串連加密認證
* 跨平台移植(Windows/Linux/Unix)
* 開放原始碼
3. 開發動機
現代Python程式已經廣泛的應用在商業邏輯,資料分析和科學計算等方面。其中廣泛應用著SMP(多處理器或多核)和叢集(通過網路連接的多台計 算機),市場需要並行的執行的Python代碼。
在SMP電腦上編寫並行程式最簡單的方法是使用多線程。儘管如此,使用 ‘thread’ 和 ‘threading’ 模組仍然無法在位元組碼一級實現並行。因為Python解譯器使用GIL(全域解譯器鎖)來在內部禁止並存執行。這個GIL限制你在SMP機器上同一時間也 只能執行一條位元組碼指令。
PP 模組正是為瞭解決這個問題而來,提供簡單的方式實現並行Python應用。 ppsmp 在內部使用 進程 和 IPC (處理序間通訊)來組織並行計算。並處理了所有內部的細節和複雜性,你的應用程式只需要提交工作任務並取回結果就可以了。這也是編寫並行程式的最簡單的方 法。
為了更好的實現,所有使用 PP 的軟體通過網路來串連和協作。跨平台和動態負載平衡使得 PP 可以輕鬆組織多平台、異構的叢集計算環境。
以官方例子:
#-*- coding: UTF-8 -*-#-------------------------------------------------------------------------------# Name: # Purpose: ## Author: ankier## Created: 05-02-2013# Copyright: (c) ankier 2013# Licence: <your licence>#-------------------------------------------------------------------------------import math, sys, timeimport ppdef IsPrime(n): """返回n是否是素數""" if not isinstance(n, int): raise TypeError("argument passed to is_prime is not of 'int' type") if n < 2: return False if n == 2: return True max = int(math.ceil(math.sqrt(n))) i = 2 while i <= max: if n % i == 0: return False i += 1 return Truedef SumPrimes(n): """計算從2-n之間的所有素數之和""" return sum([x for x in xrange(2,n) if IsPrime(x)])inputs = (100000, 100100, 100200, 100300, 100400, 100500, 100600, 100700)start_time = time.time()for input in inputs: print SumPrimes(input)print '單線程執行,總耗時', time.time() - start_time, 's'# tuple of all parallel python servers to connect withppservers = ()#ppservers = ("10.0.0.1",)if len(sys.argv) > 1: ncpus = int(sys.argv[1]) # Creates jobserver with ncpus workers job_server = pp.Server(ncpus, ppservers=ppservers)else: # Creates jobserver with automatically detected number of workers job_server = pp.Server(ppservers=ppservers)print "pp 可以用的工作核心線程數", job_server.get_ncpus(), "workers"start_time = time.time()jobs = [(input, job_server.submit(SumPrimes,(input,), (IsPrime,), ("math",))) for input in inputs]for input, job in jobs: print "Sum of primes below", input, "is", job()print "多線程下執行耗時: ", time.time() - start_time, "s"job_server.print_stats()
運行結果:
454396537454996777455898156456700218457603451458407033459412387460217613單線程執行,總耗時 3.15899991989 spp 可以用的工作核心線程數 4 workersSum of primes below 100000 is 454396537Sum of primes below 100100 is 454996777Sum of primes below 100200 is 455898156Sum of primes below 100300 is 456700218Sum of primes below 100400 is 457603451Sum of primes below 100500 is 458407033Sum of primes below 100600 is 459412387Sum of primes below 100700 is 460217613多線程下執行耗時: 1.44400000572 sJob execution statistics: job count | % of all jobs | job time sum | time per job | job server 8 | 100.00 | 5.2460 | 0.655750 | localTime elapsed since server creation 1.444000005720 active tasks, 4 cores