[英]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.