python - ThreadPoolExecutor能否帮助单线程应用效率提升?

标签 python multithreading tornado event-driven concurrent.futures

我们想要制作一个电子商务应用程序,团队是Python开发人员,但不使用Python Web框架(Django/Flask...),并且因为我们发现Tornado因其简单性而非常优秀,所以我们给了他一个很大的比例。

但问题是,Tornado是单线程的,应用程序将使用哈希(登录)和图像处理(缩略图生成)。 ThreadPoolExecutor 能否像本例中那样扮演 Apache 等多线程服务器的角色?

from concurrent.futures import ThreadPoolExecutor
from tornado import gen
from tornado.process import cpu_count
import bcrypt


pool = ThreadPoolExecutor(cpu_count())

@gen.coroutine
def create_user(name, password):
    hashed_pw = yield pool.submit(bcrypt.hashpw, password, bcrypt.gensalt())
    yield save_user(name, hashed_pw)

@gen.coroutine
def login(name, password):
    user = yield load_user(name)
    match = yield pool.submit(bcrypt.checkpw, password, user.hashed_pw)
    if not match:
        raise IncorrectPasswordError()

因此,Tornado 将哈希工作发送到另一个线程,以释放自己并能够接收其他请求。这种方法行得通吗?

注意:还有一个涉及负载均衡器的解决方案,但团队现在不想采用该解决方案。

最佳答案

是的,ThreadPoolExecutor在这里可以很好地工作。看起来都是 hashpwcheckpw在其操作的 CPU 密集部分期间释放 GIL:

bcrypt_hashpw(PyObject *self, PyObject *args, PyObject *kw_args)
{
    ...
    Py_BEGIN_ALLOW_THREADS;
    ret = pybc_bcrypt(password_copy, salt_copy, hashed, sizeof(hashed));
    Py_END_ALLOW_THREADS;
    ...

这意味着您将能够将工作分配给一个 CPU,同时使用另一个 CPU 处理传入请求。

请记住,如果您需要执行一些其他运行纯 Python 的 CPU 密集型操作(意味着 GIL 不会被释放),您将需要使用 ProcessPoolExecutor以避免性能受到影响。

关于python - ThreadPoolExecutor能否帮助单线程应用效率提升?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28243430/

相关文章:

python - python原生数据结构 "DICTIONARY"和 "Redis"数据库有什么区别?

python - 无法使用 imaplib 从 gmail 解析 url

c - 无法将结构传递给 C 中的线程函数

java - 集群上 weblogic 的 EJB 计时器的替代方案

python - Tornado 代码部署

python - 正确使用列表理解 - python

java - 在多线程环境中使用Java Singleton实例

python - Tornado中唤醒 sleep 后台方法

python-3.x - 如何与 Tornado IOLoop同时运行长时间运行的阻止功能

python - 使用 Raptor 或 Sax 验证 RDF 文件