同时运行多个独立的python脚本

时间:2017-11-28 18:44:49

标签: python multithreading subprocess multiprocessing

我的目标是创建一个主要的python脚本,同时在Windows Server 2012中执行多个独立的python脚本。我认为的一个好处是,我可以将taskscheduler指向一个CREATE TABLE BetaValues ( idBetaValues INTEGER PRIMARY KEY, Name STRING (20) NOT NULL UNIQUE, [Values] TEXT UNIQUE ); 脚本,而不是多个main.py脚本。我的服务器有1个CPU。我已阅读.pymultiprocessing& thread这只会增加我的困惑。在美国东部时间9:30开市后,我基本上同时为不同的股票代码运行多个交易脚本。以下是我的尝试,但我不知道这是否正确。任何方向/反馈都非常感谢!

subprocess

3 个答案:

答案 0 :(得分:2)

我想我会尝试这样做:

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调用,您将遇到网络带宽问题:)

答案 1 :(得分:2)

虽然您提出的问题可能并不是处理您所做事情的最佳方式,但我过去也想做类似的事情,我需要一段时间才能找到我需要的东西所以回答你的问题:

我并不承诺这是最好的"这样做的方法,但它在我的用例中起作用。

我创建了一个我想用来扩展线程的类。

thread.py

"""
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

答案 2 :(得分:1)

如果您要做的只是自动启动,那么创建.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的完整语法here