簡體   English   中英

同時運行多個獨立的python腳本

[英]Running multiple independent python scripts concurrently

我的目標是創建一個主要的python腳本,該腳本同時在Windows Server 2012中執行多個獨立的python腳本。 我心中的好處之一是,我可以將taskscheduler指向一個main.py腳本,而不是多個.py腳本。 我的服務器有1個CPU。 我讀過有關multiprocessingthreadsubprocess ,這只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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM