在thread和process中,應當優選process,因為process更穩定,而且,process可以分布到多台機器上,而thread最多只能分布到同一臺機器的多個cpu上。
python的multiprocessing
模組不但支援多程序,其中managers
子模組還支援把多程序分布到多台機器上。乙個服務程序可以作為排程者,將任務分布到其他多個程序中,依靠網路通訊。由於managers
模組封裝很好,不必了解網路通訊的細節,就可以很容易地編寫分布式多程序程式。
舉個例子:如果我們已經有乙個通過queue
通訊的多程序程式在同一臺機器上執行,現在,由於處理任務的程序任務繁重,希望把傳送任務的程序和處理任務的程序分布到兩台機器上。怎麼用分布式程序實現?
原有的queue
可以繼續使用,但是,通過managers
模組把queue
通過網路暴露出去,就可以讓其他機器的程序訪問queue
了。
我們先看服務程序,服務程序負責啟動queue
,把queue
註冊到網路上,然後往queue
裡面寫入任務:
task_master.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import random, time, queue
from multiprocessing import freeze_support
from multiprocessing.managers import basemanager
# 傳送任務的佇列:
task_queue = queue.queue()
# 接收結果的佇列:
result_queue = queue.queue()
# 從basemanager繼承的queuemanager:
class queuemanager(basemanager):
pass
def return_task_queue():
global task_queue
return task_queue
def return_result_queue():
global result_queue
return result_queue
def test():
# 把兩個queue都註冊到網路上, callable引數關聯了queue物件:
# queuemanager.register('get_task_queue', callable=lambda: task_queue)
# queuemanager.register('get_result_queue', callable=lambda: result_queue)
queuemanager.register('get_task_queue', callable=return_task_queue)
queuemanager.register('get_result_queue', callable=return_result_queue)
# 繫結埠5000, 設定驗證碼'abc':
manager = queuemanager(address=('127.0.0.1', 5000), authkey=b'abc')
# 啟動queue:
manager.start()
# 獲得通過網路訪問的queue物件:
task = manager.get_task_queue()
result = manager.get_result_queue()
# 放幾個任務進去:
for i in range(10):
n = random.randint(0, 10000)
print('put task %d...' % n)
task.put(n)
# 從result佇列讀取結果:
print('try get results...')
for i in range(10):
r = result.get(timeout=10)
print('result: %s' % r)
# 關閉:
manager.shutdown()
print('master exit.')
if __name__ == '__main__':
freeze_support()
test()
task_woker.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time, sys, queue
from multiprocessing.managers import basemanager
# 建立類似的queuemanager:
class queuemanager(basemanager):
pass
# 由於這個queuemanager只從網路上獲取queue,所以註冊時只提供名字:
queuemanager.register('get_task_queue')
queuemanager.register('get_result_queue')
# 連線到伺服器,也就是執行task_master.py的機器:
server_addr = '127.0.0.1'
print('connect to server %s...' % server_addr)
# 埠和驗證碼注意保持與task_master.py設定的完全一致:
m = queuemanager(address=(server_addr, 5000), authkey=b'abc')
# 從網路連線:
m.connect()
# 獲取queue的物件:
task = m.get_task_queue()
result = m.get_result_queue()
# 從task佇列取任務,並把結果寫入result佇列:
for i in range(10):
try:
n = task.get(timeout=1)
print('run task %d * %d...' % (n, n))
r = '%d * %d = %d' % (n, n, n*n)
time.sleep(1)
result.put(r)
except queue.empty:
print('task queue is empty.')
# 處理結束:
print('worker exit.')
請注意,當我們在一台機器上寫多程序程式時,建立的queue
可以直接拿來用,但是,在分布式多程序環境下,新增任務到queue
不可以直接對原始的task_queue
進行操作,那樣就繞過了queuemanager
的封裝,必須通過manager.get_task_queue()
獲得的queue
介面新增。
這個簡單的master/worker模型有什麼用?其實這就是乙個簡單但真正的分布式計算,把**稍加改造,啟動多個worker,就可以把任務分布到幾台甚至幾十台機器上,比如把計算n*n
的**換成傳送郵件,就實現了郵件佇列的非同步傳送。
在Windows下利用Python控制Linux
在windows下如何能控制linux,大概的想法肯定是ssh,的確,python也提供了對應的庫,以下先提供乙個例子,通過python獲得xenserver的uuid import paramiko hostname 10.10.10.100 port 22 username root passw...
python在windows下的備份程式
我看的是 python簡易教程 裡面講的是在linux下的,我懶得切換系統,就像在xp上測試一下,都差不多相同,就是到執行打包的時候是不一樣的。要用到winrar,其他的壓縮檔案也是一樣的。首先我們要把winrar的路徑新增到path裡面,這裡新增完了要重啟機子才有效。ps 我就糾結在這裡n久,為什...
PYTHON在WINDOWS環境下的環境變數設定
1.首先需要在系統中註冊python環境變數 假設python的安裝路徑為c python2.5,開啟 我的電腦 屬性 高階 環境變數 系統變數 在path的值後面追加 c python25 記得加上 分號 與前面的值分隔開 上述環境變數設定成功之後,就可以在命令列直接使用python命令。或執行 ...