烧瓶:如果我计算请求,我无法执行多线程



我有一个Flask API,它应该得到一个请求,用selenium做一些事情,然后返回一些东西给用户。

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

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

/p>为了避免所有线程覆盖同一个文件,我修改了代码,包括counter变量,它的作用就像一个请求计数器(从这个回答增量计数器到每次访问Flask视图-答案)。

下面的代码将为每个请求创建一个名为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分别处理了所有不同的请求(但代码仍然没有表现为我想要的,因为覆盖问题)

我怎样才能计算所有的请求,并且仍然能够处理它们中的每个请求,同时同时处理多个请求?

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

而不是:

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

最新更新