繁体   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