如何根据条件限制线程数,而不阻塞主要线程

时间:2017-10-13 17:47:04

标签: python multithreading flask queue

我想根据条件限制线程数,而不会阻止主线程,因为主要线程正在运行一个烧瓶应用程序。

该应用程序的端点可触发子流程中的某些作业,每个作业都在自己的线程中运行。在该过程结束时,将在数据库中更新条目。为简单起见,我们假设它正在执行的命令只是一个普通的echo $something。以下部分代码:

# job_runner.py

import threading
import subprocess

def popen_with_callback(self, echo):
    """Run subprocess in a separate thread.

    starts subprocess in a separate thread --> adds new entry to the jobs table
    --> updates jobs.return_code on completion --> returns thread
    """
    def run_in_thread(echo):
        command = [
            "bash", "-c",
            "for ((i=0;i<100;i=i+1)); do echo %s; sleep 1; done" %(echo)
        ]
        proc = subprocess.Popen(
            command,
            shell=False
        )

        # add job to database
        models.Job.create_job(proc.pid, ..., ...)
        proc.wait()

        # update job return code on exit
        models.Job.update_return_code(proc.returncode, ...)

    thread = threading.Thread(target=run_in_thread, args=(echo))
    thread.daemon = True
    thread.start()
    return thread

假设我的端点只接受一个参数,并基于此,它将该参数作为参数触发popen_with_callback

# some_view.py

from . import job_runner

@app.route('/run_job', methods=['POST'])
def run_job():
    data = request.get_json()
    echo = data['echo']
    job_runner.popen_with_callback(echo)

所以这种方法工作正常,因为主线程继续运行应用程序并且作为仅运行os进程的线程触发作业,因此应用程序本身没有重负载。

问题是,实际上一些运行的命令是CPU密集型的,我想在调用这样的作业时限制并发线程。因此,我们假设贪婪的资源称为i_use_cpu_like_crazy,其他资源称为easy_peasy

我想将使用大量CPU的进程数量限制为只有一个,而不关心可能的其他进程,但我无法理解如何在不阻塞主线程的情况下实现这种机制,可能使用QueuePoolSemaphore ...

这个想法如下:

curl -X POST -H "Content-type: application/json" http://localhost:5000/run_job -d '{"echo": "i_use_cpu_like_crazy"}'

1)如果还有另一个进程i_use_cpu_like_crazy已经运行,请将此新进程添加到队列中,并在正在运行的进程完成时触发它

curl -X POST -H "Content-type: application/json" http://localhost:5000/run_job -d '{"echo": "easy_peasy"}'

2)只需创建线程并运行该过程而不进行任何检查

0 个答案:

没有答案
相关问题