鍍金池/ 教程/ Python/ Parallel Python 實(shí)現(xiàn)程序的并行多 cpu 多核利用【pp 模塊】
通過 memcached 實(shí)現(xiàn)領(lǐng)號排隊(duì)功能及 python 隊(duì)列實(shí)例
利用 pypy 提高 python 腳本的執(zhí)行速度及測試性能
Python FAQ3-python 中 的原始(raw)字符串
Mongodb 千萬級數(shù)據(jù)在 python 下的綜合壓力測試及應(yīng)用探討
Parallel Python 實(shí)現(xiàn)程序的并行多 cpu 多核利用【pp 模塊】
python simplejson 模塊淺談
服務(wù)端 socket 開發(fā)之多線程和 gevent 框架并發(fā)測試[python 語言]
python Howto 之 logging 模塊
python 之 MySQLdb 庫的使用
關(guān)于 python 調(diào)用 zabbix api 接口的自動化實(shí)例 [結(jié)合 saltstack]
python 之利用 PIL 庫實(shí)現(xiàn)頁面的圖片驗(yàn)證碼及縮略圖
Python 通過 amqp 消息隊(duì)列協(xié)議中的 Qpid 實(shí)現(xiàn)數(shù)據(jù)通信
python 中用 string.maketrans 和 translate 巧妙替換字符串
python linecache 模塊讀取文件用法詳解
Python 批量更新 nginx 配置文件
python 計(jì)算文件的行數(shù)和讀取某一行內(nèi)容的實(shí)現(xiàn)方法
python+Django 實(shí)現(xiàn) Nagios 自動化添加監(jiān)控項(xiàng)目
多套方案來提高 python web 框架的并發(fā)處理能力
python 寫報(bào)警程序中的聲音實(shí)現(xiàn) winsound
python 調(diào)用 zabbix 的 api 接口添加主機(jī)、查詢組、主機(jī)、模板
對 Python-memcache 分布式散列和調(diào)用的實(shí)現(xiàn)
使用 python 構(gòu)建基于 hadoop 的 mapreduce 日志分析平臺
一個(gè)腳本講述 python 語言的基礎(chǔ)規(guī)范,適合初學(xué)者
Python 編寫的 socket 服務(wù)器和客戶端
如何將 Mac OS X10.9 下的 Python2.7 升級到最新的 Python3.3
python 監(jiān)控文件或目錄變化
報(bào)警監(jiān)控平臺擴(kuò)展功能 url 回調(diào)的設(shè)計(jì)及應(yīng)用 [python 語言]
Python 處理 cassandra 升級后的回滾腳本
python 實(shí)現(xiàn) select 和 epoll 模型 socket 網(wǎng)絡(luò)編程
關(guān)于 B+tree (附 python 模擬代碼)
通過 python 和 websocket 構(gòu)建實(shí)時(shí)通信系統(tǒng)[擴(kuò)展 saltstack 監(jiān)控]

Parallel Python 實(shí)現(xiàn)程序的并行多 cpu 多核利用【pp 模塊】

 為啥要這個(gè)模塊:

Python 是解釋型的語言,而 Python 解釋器使用 GIL(全局解 釋器鎖)來在內(nèi)部禁止并行執(zhí)行,正是這個(gè) GIL 限制你在多核處理器上同一時(shí)間也只能執(zhí)行一條字節(jié)碼指令. 聽朋友說 python 3.0 里面已經(jīng)改進(jìn), 默認(rèn)有了多處理器編程的庫了. Python2.XX 暫時(shí)還不支持。

Parallel Python 這個(gè)庫,正是為支持 smp 多路多核多 cpu 而設(shè)計(jì)的, 而且它不僅可以多核處理器協(xié)同工作,還可以通過網(wǎng)絡(luò)集群運(yùn)行。

官網(wǎng):
http://www.parallelpython.com/

pp 模塊的簡介

PP 是一個(gè) Python 模塊,提供了在 SMP(多 CPU 或多核)和集群(通過網(wǎng)絡(luò)連接的多臺計(jì)算機(jī))上并行執(zhí)行 Python 代碼的機(jī)制。輕量級,易于安裝,并 集成了其他軟件。PP 也是一個(gè)用純 Python 代碼實(shí)現(xiàn)的跨平臺,開放源碼模塊。

下面是看起來很高端的功能介紹!

  • 在 SMP 和集群上并行執(zhí)行 Python 代碼
  • 易于理解和實(shí)現(xiàn)的基于工作的并行機(jī)制,便于把穿行應(yīng)用轉(zhuǎn)換成并行的
  • 自動構(gòu)造最佳配置(默認(rèn)時(shí)工作進(jìn)程數(shù)量等同于系統(tǒng)處理器數(shù)量)
  • 動態(tài)處理器分配(允許運(yùn)行時(shí)改變工作處理器數(shù)量)
  • 函數(shù)的工作緩存(透明的緩存機(jī)制確保后續(xù)調(diào)用降低負(fù)載)
  • 動態(tài)負(fù)載均衡(任務(wù)被動態(tài)的分配到各個(gè)處理器上)
  • 基于 SHA 的連接加密認(rèn)證
  • 跨平臺移植(Windows/Linux/Unix)
  • 開放源代碼

有些朋友可能對并發(fā)和并行理解有點(diǎn)亂,在這里梳理下哈:

當(dāng)有多個(gè)線程在操作時(shí),如果系統(tǒng)只有一個(gè) CPU,則它根本不可能真正同時(shí)進(jìn)行一個(gè)以上的線程,它只能把 CPU 運(yùn)行時(shí)間劃分成若干個(gè)時(shí)間段,再將時(shí)間 段分配給各個(gè)線程執(zhí)行,在一個(gè)時(shí)間段的線程代碼運(yùn)行時(shí),其它線程處于掛起狀態(tài).這種方式我們稱之為并發(fā)(Concurrent).
當(dāng)系統(tǒng)有一個(gè)以上 CPU 時(shí),則線程的操作有可能非并發(fā).當(dāng)一個(gè) CPU 執(zhí)行一個(gè)線程時(shí),另一個(gè) CPU 可以執(zhí)行另一個(gè)線程,兩個(gè)線程互不搶占 CPU 資源,可以同時(shí)進(jìn)行,這種方式我們稱之為并行(Parallel)

地址:http://rfyiamcool.blog.51cto.com/1030776/1357112

多線程在并發(fā)和并行環(huán)境中的不同作用

在并發(fā)環(huán)境時(shí),多線程不可能真正充分利用 CPU,節(jié)約運(yùn)行時(shí)間,它只是以”掛起->執(zhí)行->掛起”的方式以很小的時(shí)間片分別運(yùn)行各個(gè)線程,給用戶以每個(gè)線程都在運(yùn)行的錯(cuò)覺.在這種環(huán)境中,多線程程序真正改善的是系統(tǒng)的響應(yīng)性能和程序的友好性.
在并行環(huán)境中, 一個(gè)時(shí)刻允許多個(gè)線程運(yùn)行,這時(shí)多線程程序才真正充分利用了多 CPU 的處理能力, 節(jié)省了整體的運(yùn)行時(shí)間.在這種環(huán)境中,多線程程序能體現(xiàn)出它的四大優(yōu)勢:充分利用 CPU,節(jié)省時(shí)間,改善響應(yīng)和增加程序的友好性.

并發(fā)和并行的區(qū)別就是一個(gè)處理器同時(shí)處理多個(gè)任務(wù)和多個(gè)處理器或者是多核的處理器同時(shí)處理多個(gè)不同的任務(wù)。

前者是邏輯上的同時(shí)發(fā)生(simultaneous),而后者是物理上的同時(shí)發(fā)生.

來個(gè)比喻:并發(fā)和并行的區(qū)別就是一個(gè)人同時(shí)吃三個(gè)饅頭和三個(gè)人同時(shí)吃三個(gè)饅頭。

咱們跑一下:

安裝 pp 模塊

http://wiki.jikexueyuan.com/project/python-actual-combat/images/77.jpg" alt="pic" />

好,測試

【這是單核的利用情況下】

http://wiki.jikexueyuan.com/project/python-actual-combat/images/78.jpg" alt="pic" />

開啟 python 多核的情況下

【看到?jīng)]有,多出了 4 個(gè)進(jìn)程,這四個(gè)進(jìn)程是綁在不同的 cpu上,這四個(gè) cpu 跑的很均勻】

http://wiki.jikexueyuan.com/project/python-actual-combat/images/79.jpg" alt="pic" />

測試的代碼:

#-*- coding: UTF-8 -*-
import math, sys, time
import pp
def IsPrime(n):
    """返回 n 是否是素?cái)?shù)"""
    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 True
def SumPrimes(n):
    for i in xrange(15):
        sum([x for x in xrange(2,n) if IsPrime(x)])
    """計(jì)算從 2-n 之間的所有素?cái)?shù)之和"""
    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 '單線程執(zhí)行,總耗時(shí)', time.time() - start_time, 's'
# tuple of all parallel python servers to connect with
ppservers = ()
#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 可以用的工作核心線程數(shù)", 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 "多線程下執(zhí)行耗時(shí): ", time.time() - start_time, "s"
job_server.print_stats()

pp 的官方例子給的很足,也相當(dāng)?shù)暮喚殻?/p>

導(dǎo)入讓 python 支持多核心的模塊

1) Import pp module:

import pp

一個(gè)實(shí)例,含有cpu的核心數(shù)目 2) Start pp execution server with the number of workers set to the number of processors in the system

job_server = pp.Server()

可以支持網(wǎng)絡(luò)的分布式運(yùn)算!

# tuple of all parallel python servers to connect with
ppservers = ()
#ppservers = ("10.0.0.1",)
ncpus = int(sys.argv[1])
# Creates jobserver with ncpus workers
job_server = pp.Server(ncpus, ppservers=ppservers)

3) Submit all the tasks for parallel execution:

f1 = job_server.submit(func1, args1, depfuncs1, modules1)

f2 = job_server.submit(func1, args2, depfuncs1, modules1)

f3 = job_server.submit(func2, args3, depfuncs2, modules2)
...etc...

4) Retrieve the results as needed:

r1 = f1()

r2 = f2()

r3 = f3()

...etc...

剛才說了 parallet python 是支持網(wǎng)絡(luò)的分布式運(yùn)算集群的!

Advanced guide, clusters

On the nodes

1) Start parallel python execution server on all your remote computational nodes (listen to a given port 35000, and local network interface only, accept only connections which know correct secret):

node-1> ./ppserver.py -p 35000 -i 192.168.0.101 -s "mysecret"

node-2> ./ppserver.py -p 35000 -i 192.168.0.102 -s "mysecret"

node-3> ./ppserver.py -p 35000 -i 192.168.0.103 -s "mysecret"

On the client

2) Import pp module:

import pp

3) Create a list of all the nodes in your cluster (computers where you've run ppserver.py)

ppservers=("node-1:35000", "node-2:35000", "node-3:35000")

4) Start pp execution server with the number of workers set to the number of processors in the system, list of ppservers to connect with and secret key to authorize the connection:

job_server = pp.Server(ppservers=ppservers, secret="mysecret")

5) Submit all the tasks for parallel execution:

f1 = job_server.submit(func1, args1, depfuncs1, modules1)

f2 = job_server.submit(func1, args2, depfuncs1, modules1)

f3 = job_server.submit(func2, args3, depfuncs2, modules2) ...etc...

6) Retrieve the results as needed:

r1 = f1()

r2 = f2()

r3 = f3()

...etc...

7) Print the execution statistics:

job_server.print_stats()

http://wiki.jikexueyuan.com/project/python-actual-combat/images/80.jpg" alt="pic" />

地址:http://rfyiamcool.blog.51cto.com/1030776/1357112

這里有很多的例子,大家可以跑跑!

http://www.parallelpython.com/content/view/17/31/

安裝 python 的 pp 模塊直接運(yùn)行就行

本文出自 “峰云,就她了。” 博客,謝絕轉(zhuǎn)載!