[英]Running multiple independent python scripts concurrently
我的目標是創建一個主要的python腳本,該腳本同時在Windows Server 2012中執行多個獨立的python腳本。 我心中的好處之一是,我可以將taskscheduler指向一個main.py
腳本,而不是多個.py
腳本。 我的服務器有1個CPU。 我讀過有關multiprocessing
, thread
和subprocess
,這只subprocess
我感到困惑。 在美國東部標准時間9:30開市后,我基本上同時針對不同的股票代碼運行多個交易腳本。 以下是我的嘗試,但我不知道這是否正確。 任何方向/反饋都非常感謝!
import subprocess
subprocess.Popen(["python", '1.py'])
subprocess.Popen(["python", '2.py'])
subprocess.Popen(["python", '3.py'])
subprocess.Popen(["python", '4.py'])
我想我會嘗試這樣做:
from multiprocessing import Pool
def do_stuff_with_stock_symbol(symbol):
return _call_api()
if __name__ == '__main__':
symbols = ["GOOG", "APPL", "TSLA"]
p = Pool(len(symbols))
results = p.map(do_stuff_with_stock_symbol, symbols)
print(results)
(來自多處理簡介的修改示例: https : //docs.python.org/3/library/multiprocessing.html#introduction )
如果處理大量的股票代號,請考慮使用恆定的池大小,因為每個python進程都會使用一定數量的內存。
另外,請注意,如果您要處理受I / O約束的工作負載(調用API,從磁盤寫入和讀取),則使用線程可能會更好。 在處理計算綁定的工作負載時(由於全局解釋器鎖),使用python確實確實需要進程。
使用線程和並發期貨庫的示例為:
import concurrent.futures
TIMEOUT = 60
def do_stuff_with_stock_symbol(symbol):
return _call_api()
if __name__ == '__main__':
symbols = ["GOOG", "APPL", "TSLA"]
with concurrent.futures.ThreadPoolExecutor(max_workers=len(symbols)) as executor:
results = {executor.submit(do_stuff_with_stock_symbol, symbol, TIMEOUT): symbol for symbol in symbols}
for future in concurrent.futures.as_completed(results):
symbol = results[future]
try:
data = future.result()
except Exception as exc:
print('{} generated an exception: {}'.format(symbol, exc))
else:
print('stock symbol: {}, result: {}'.format(symbol, data))
(修改后的示例來自: https : //docs.python.org/3/library/concurrent.futures.html#threadpoolexecutor-example )
請注意,線程仍將使用一些內存,但少於進程。
如果您想將每個股票代號的內存消耗降至最低,則可以使用asyncio或綠色線程,但是在某些時候,由於所有並發API調用,您都會遇到網絡帶寬問題:)
雖然您要問的問題可能不是處理您正在做的事情的最佳方法,但過去我想做類似的事情,並且花了一段時間才找到我需要的東西,才能回答您的問題:
我不保證這是實現此目的的“最佳”方法,但它在我的用例中有效。
我創建了一個我想用來擴展線程的類。
線程
"""
Extends threading.Thread giving access to a Thread object which will accept
A thread_id, thread name, and a function at the time of instantiation. The
function will be called when the threads start() method is called.
"""
import threading
class Thread(threading.Thread):
def __init__(self, thread_id, name, func):
threading.Thread.__init__(self)
self.threadID = thread_id
self.name = name
# the function that should be run in the thread.
self.func = func
def run(self):
return self.func()
我需要做一些其他包裝中的工作
work_module.py
import...
def func_that_does_work():
# do some work
pass
def more_work():
# do some work
pass
然后我要運行main.py的主腳本
from thread import Thread
import work_module as wm
mythreads = []
mythreads.append(Thread(1, "a_name", wm.func_that_does_work))
mythreads.append(Thread(2, "another_name", wm.more_work))
for t in mythreads:
t.start()
返回run()時,線程死亡。 由於這是從線程擴展線程的原因,此處的文檔中提供了幾個選項: https : //docs.python.org/3/library/threading.html
如果您要做的只是自動化啟動,那么創建.bat文件是嘗試使用另一個python腳本的絕佳簡便選擇。
注釋中鏈接的示例顯示了如何在基於unix的計算機上使用bash進行操作,但是批處理文件可以使用START
命令執行非常相似的操作:
start_py.bat:
START "" /B "path\to\python.exe" "path\to\script_1.py"
START "" /B "path\to\python.exe" "path\to\script_2.py"
START "" /B "path\to\python.exe" "path\to\script_3.py"
START
的完整語法可以在這里找到。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.