2016-08-25 63 views
0

我是python multiprocessing的新手。我正在嘗試使用third-party web-API爲多個感興趣的符號獲取數據。這裏是我的Python代碼:Python多處理:子進程以不同的速度工作

<!-- language:lang-py--> 

def my_worker(symbol, table_name): 
    while True: 
     # Real-time data for the symbol, third party code which is verified 
     data = webApi.getData(symbol) 
     query = ('insert into ' + table_name + '(var1, var2) values("%s, %s")' %(data[0], data[1])) 
     # Execute query and store the data. Omitted for sake of brevity 

if __name__ == "__main__": 
    my_symbols = get_symbols_list() # List of symbols 
    my_tables = get_tables_list() # Corresponding list of mysql tables 
    jobs = [] 
    for pidx in range(len(my_symbols)): 
     pname = 'datarecorder_' + my_symbols[pidx] # Naming the process for later identification 
     p = multiprocessing.Process(name=pname, target=my_worker, args=(my_symbols[pidx], my_tables[pidx],)) 
     jobs.append(p) 
     p.start() 

在這段代碼中大約有50 processes created

問題,即我面對:是,當我看到相應的表中一定量的時間之後(如5分鐘),在每個在my_tables表中的記錄的數量是顯着地不同(大約10的倍數)

因爲我使用相同的API,相同的網絡連接和相同的代碼來獲取和寫入數據到MySQL表,我不知道是什麼造成了這種差異記錄數。 My hunch is that each of the 50 processes is getting assigned an unequal amount of RAM and other resources, and perhaps the priority is also different(?)

有人能告訴我如何確保每個這些進程輪詢webApi大致相同的次數?

+0

_on的倍數爲10s_ 您的意思是說某些表格中有50個以上的記錄,或者某些表格的記錄數量是其他記錄的50倍?調度不是確定性的\ *,所以你不能,因此也不應該依賴它以任何特定的方式行事。公平是目標,但不能保證實時調度。 \ *有關確定性的有用定義。 – Cubic

+0

我的意思是5分鐘後某些表格將有10-20條記錄,而其他表格可能有200-300條記錄。如果公平是目標,這些表格中的記錄數應該大致相等,並且多少或多或少的記錄不會對我造成傷害,但是這種差異的順序太不容忽視。 – joshi

+0

對我來說,使用[multiprocessing.Pool](https://docs.python.org/3/library/multiprocessing.html#module-multiprocessing。(例如apply_async或map),而不是直接創建所有進程,因爲創建新進程需要一些時間 - 也許這就是時間問題的原因 – janbrohl

回答

0

解決這些問題的一個有效方法是從一個非常簡單的事情開始,然後添加東西,直到出現「問題」。否則,它只是盲目的猜測。

例如,這裏的東西要簡單得多,這我在Windows下運行(如你 - 我使用的是當前的Win10專業版)和Python 3.5.2:

import multiprocessing as mp 
from time import sleep 

NPROCS = 50 

def worker(i, d): 
    while True: 
     d[i] += 1 
     sleep(1) 

if __name__ == "__main__": 
    d = mp.Manager().dict() 
    for i in range(NPROCS): 
     d[i] = 0 

    ps = [] 
    for i in range(NPROCS): 
     p = mp.Process(target=worker, args=(i, d)) 
     ps.append(p) 
     p.start() 

    while True: 
     sleep(3) 
     print(d.values()) 

下面是最近輸出後約一分鐘跑:

[67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 
67, 67, 67, 67, 67, 67, 67, 67, 67, 66, 
66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 
66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 
66, 66, 66, 66, 66, 66, 66, 66, 66, 66] 

因此我可以斷定,沒有什麼「本質上不公平的」關於此框進程調度。在你的盒子上?運行它並查看;-)

我也可以在任務管理器中看到所有50個進程都被類似地處理,例如具有相同的RAM使用和優先級。僅供參考,這個盒子恰好有8個邏輯核心(4個物理),並且有足夠的RAM(16GB)。

現在,你在做什麼還有其他複雜的世界,我們從這裏可以猜出任何一個。例如,也許你的內存不足,所以一些進程會因頁面文件交換而大大延遲。或者,你所做的工作比其他人花費的時間要長得多。或者......不過,無論如何,最簡單的方法是逐步製作一個非常簡單的程序。