Flask:如果我计算请求我不能做多线程

Flask: if I count requests I can't do multithreading

我有一个 Flask API 应该收到请求,用 selenium 做一些事情,然后 return 给用户一些事情。

版本 1

import flask
from multiprocessing import Value
from selenium import webdriver

app = flask.Flask(__name__)
app.config["DEBUG"] = False
@app.route('/api/url', methods=['GET', 'POST'])

def site():
    # do some stuff ...
    with open(os.path.normpath(os.getcwd() + "\file.mp3"), 'wb') as f:
        f.write(<something>)
    # ... do some other stuff and return a variable

def home():
    return "<h1>Distant Reading Archive</h1><p>This site is a prototype API for distant reading of science fiction novels.</p>"

app.run(host="0.0.0.0", threaded=True)

这段代码在技术上可以完美运行,如果不是我需要同时管理多个请求:例如,如果我同时处理两个请求,第二个请求将覆盖file 在第一个请求创建的文件上,这将是一个问题。

版本 2

为了避免所有线程都覆盖同一个文件,我通过包含 counter 变量来更改代码,该变量充当请求计数器(来自此答案 )。

以下代码将为每个请求创建一个名为 file<n>.mp3 的文件,其中 <n> 是请求的编号(第 <n> 个请求),因此我将每个请求都有不同的文件。

import flask
from multiprocessing import Value
from selenium import webdriver

app = flask.Flask(__name__)
app.config["DEBUG"] = False
@app.route('/api/url', methods=['GET', 'POST'])

counter = Value('i', 0)

def site():
    with counter.get_lock():
        counter.value += 1
        out = counter.value
        # do some stuff ...
        with open(os.path.normpath(os.getcwd() + "\file{}.mp3".format(out)), 'wb') as f:
            f.write(<something>)
        # ... do some other stuff and return a variable

def home():
    return "<h1>Distant Reading Archive</h1><p>This site is a prototype API for distant reading of science fiction novels.</p>"

app.run(host="0.0.0.0", threaded=True)

版本 2 有问题

代码版本 2 的问题是多线程显然停止工作,代码一次只处理一个请求。

多线程停止工作的事实似乎与我包含计数器的事实有关,因为在版本 1 中多线程确实工作并且 API 分别处理所有不同的请求(但代码仍然没有由于覆盖问题,我的行为就像我想要的那样)

问题

我如何计算所有请求并仍然设法在其 own/with 其文件中处理每个请求,同时同时处理多个请求?

问题是 with counter.get_lock() 中包含了太多代码。只要你有这个锁,其他线程就不能运行.

相反你想要:

with counter.get_lock():
    counter.value += 1
    out = counter.value
do rest of the stuff outside of the lock