Python在windows下的分布式程序

2021-08-10 15:19:31 字數 3797 閱讀 4148

在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命令。或執行 ...