多线程的Python的Django

问题描述 投票:33回答:4

有些功能应该在Web服务器上异步运行。发送电子邮件或数据后处理是典型的用例。

什么是最好的(或最Python的)方式写一个装饰功能异步运行的功能?

我的设置是常见的一种:Python和Django的,Gunicorn或服务员,AWS EC2标准的Linux

例如,这里是一个开始:

from threading import Thread

def postpone(function):
    def decorator(*args, **kwargs):
        t = Thread(target = function, args=args, kwargs=kwargs)
        t.daemon = True
        t.start()
    return decorator

期望的使用:

@postpone
def foo():
    pass #do stuff
python django multithreading decorator python-multithreading
4个回答
60
投票

我已经使用在规模和生产没有问题,这继续实施。

装饰定义:

def start_new_thread(function):
    def decorator(*args, **kwargs):
        t = Thread(target = function, args=args, kwargs=kwargs)
        t.daemon = True
        t.start()
    return decorator

实例:

@start_new_thread
def foo():
  #do stuff

随着时间的推移,堆栈更新并没有转变失败。

最初的Python 2.4.7,Django的1.4,Gunicorn 0.17.2,现在的Python 3.6,Django的2.1,1.1服务员。

如果您正在使用的任何数据库事务,Django会创建一个新的连接,这需要手动关闭:

from django.db import connection

@postpone
def foo():
  #do stuff
  connection.close()

15
投票

Celery是一个异步任务队列/作业队列。它是有据可查的,并适合你需要的东西。我建议你开始here


3
投票

做异步处理在Django最常见的方法是使用Celerydjango-celery


0
投票

tomcounsell的做法效果很好,如果有没有太多传入的作业。如果许多长效工作在较短的时间内运行,因此产卵很多线程,主进程将受到影响。在这种情况下,你可以使用一个线程池与协同程序,

# in my_utils.py

from concurrent.futures import ThreadPoolExecutor

MAX_THREADS = 10


def run_thread_pool():
    """
    Note that this is not a normal function, but a coroutine.
    All jobs are enqueued first before executed and there can be
    no more than 10 threads that run at any time point.
    """
    with ThreadPoolExecutor(max_workers=MAX_THREADS) as executor:
        while True:
            func, args, kwargs = yield
            executor.submit(func, *args, **kwargs)


pool_wrapper = run_thread_pool()

# Advance the coroutine to the first yield (priming)
next(pool_wrapper)
from my_utils import pool_wrapper

def job(*args, **kwargs):
    # do something

def handle(request):
    # make args and kwargs
    pool_wrapper.send((job, args, kwargs))
    # return a response
© www.soinside.com 2019 - 2024. All rights reserved.