【问题标题】:Can ThreadPoolExecutor help single-threaded application efficiency?ThreadPoolExecutor 能否帮助提高单线程应用效率?
【发布时间】:2015-01-30 19:42:57
【问题描述】:

我们想做一个电子商务应用程序,团队是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 将散列工作发送到另一个线程,以释放自己并能够接收其他请求。这种方法行得通吗?

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

【问题讨论】:

    标签: python multithreading tornado event-driven concurrent.futures


    【解决方案1】:

    是的,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 以避免占用性能命中。

    【讨论】:

    • 那么,pillow 也会这样做吗?因为它们将是唯一的约束,因为所有其他的都会有它们的非阻塞驱动程序(数据库)
    • @Abdelouahab 快速查看pillow 源代码表明,他们的C 扩展确实在几个地方释放了GIL,因此至少在某些情况下它会与ThreadPoolExecutor 一起运行良好。不过,我不能肯定地说所有操作都会释放它。
    • 啊,所以这是经验法则:如果它释放了 GIL,那么我可以,否则,我优化它;)谢谢 :)
    • @Abdelouahab 差不多。尽管在大多数情况下,当您处理不发布 GIL 的代码时,您可以将 ProcessPoolExecutor 替换为 ThreadPoolExecutor。您唯一需要注意的是使用 multiprocessing 时的典型注意事项(参数/返回值的可腌制性、IPC 的开销等)
    猜你喜欢
    • 2011-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-07
    • 2017-04-20
    • 2011-02-19
    • 1970-01-01
    相关资源
    最近更新 更多