简体   繁体   English

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

[英]Running multiple independent python scripts concurrently

My goal is create one main python script that executes multiple independent python scripts in windows server 2012 at the same time. 我的目标是创建一个主要的python脚本,该脚本同时在Windows Server 2012中执行多个独立的python脚本。 One of the benefits in my mind is that I can point taskscheduler to one main.py script as opposed to multiple .py scripts. 我心中的好处之一是,我可以将taskscheduler指向一个main.py脚本,而不是多个.py脚本。 My server has 1 cpu. 我的服务器有1个CPU。 I have read on multiprocessing , thread & subprocess which only added to my confusion a bit. 我读过有关multiprocessingthreadsubprocess ,这只subprocess我感到困惑。 I am basically running multiple trading scripts for different stock symbols all at the same time after market open at 9:30 EST. 在美国东部标准时间9:30开市后,我基本上同时针对不同的股票代码运行多个交易脚本。 Following is my attempt but I have no idea whether this is right. 以下是我的尝试,但我不知道这是否正确。 Any direction/feedback is highly appreciated! 任何方向/反馈都非常感谢!

import subprocess

subprocess.Popen(["python", '1.py'])
subprocess.Popen(["python", '2.py'])
subprocess.Popen(["python", '3.py'])
subprocess.Popen(["python", '4.py'])

I think I'd try to do this like that: 我想我会尝试这样做:

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)

(Modified example from multiprocessing introduction: https://docs.python.org/3/library/multiprocessing.html#introduction ) (来自多处理简介的修改示例: https : //docs.python.org/3/library/multiprocessing.html#introduction

Consider using a constant pool size if you deal with a lot of stock symbols, because every python process will use some amount of memory. 如果处理大量的股票代号,请考虑使用恒定的池大小,因为每个python进程都会使用一定数量的内存。

Also, please note that using threads might be a lot better if you are dealing with an I/O bound workload (calling an API, writing and reading from disk). 另外,请注意,如果您要处理受I / O约束的工作负载(调用API,从磁盘写入和读取),则使用线程可能会更好。 Processes really become necessary with python when dealing with compute bound workloads (because of the global interpreter lock). 在处理计算绑定的工作负载时(由于全局解释器锁),使用python确实确实需要进程。

An example using threads and the concurrent futures library would be: 使用线程和并发期货库的示例为:

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

(Modified example from: https://docs.python.org/3/library/concurrent.futures.html#threadpoolexecutor-example ) (修改后的示例来自: https : //docs.python.org/3/library/concurrent.futures.html#threadpoolexecutor-example

Note that threads will still use some memory, but less than processes. 请注意,线程仍将使用一些内存,但少于进程。

You could use asyncio or green threads if you want to reduce memory consumption per stock symbol to a minimum, but at some point you will run into network bandwidth problems because of all the concurrent API calls :) 如果您想将每个股票代号的内存消耗降至最低,则可以使用asyncio或绿色线程,但是在某些时候,由于所有并发API调用,您都会遇到网络带宽问题:)

While what you're asking might not be the best way to handle what you're doing, I've wanted to do similar things in the past and it took a while to find what I needed so to answer your question: 虽然您要问的问题可能不是处理您正在做的事情的最佳方法,但过去我想做类似的事情,并且花了一段时间才找到我需要的东西,才能回答您的问题:

I'm not promising this to be the "best" way to do it, but it worked in my use case. 我不保证这是实现此目的的“最佳”方法,但它在我的用例中有效。

I created a class I wanted to use to extend threading. 我创建了一个我想用来扩展线程的类。

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()

I needed some work done that was part of another package 我需要做一些其他包装中的工作

work_module.py work_module.py

import...

def func_that_does_work():
    # do some work
    pass

def more_work():
    # do some work
    pass

Then the main script I wanted to run main.py 然后我要运行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()

The threads die when the run() is returned. 返回run()时,线程死亡。 Being this extends a Thread from threading there are several options available in the docs here: https://docs.python.org/3/library/threading.html 由于这是从线程扩展线程的原因,此处的文档中提供了几个选项: https : //docs.python.org/3/library/threading.html

If all you're looking to do is automate the startup, creating a .bat file is a great and simple alternative to trying to do it with another python script. 如果您要做的只是自动化启动,那么创建.bat文件是尝试使用另一个python脚本的绝佳简便选择。

the example linked in the comments shows how to do it with bash on unix based machines, but batch files can do a very similar thing with the START command: 注释中链接的示例显示了如何在基于unix的计算机上使用bash进行操作,但是批处理文件可以使用START命令执行非常相似的操作:

start_py.bat: 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"

the full syntax for START can be found here . START的完整语法可以在这里找到。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM