Как создать поток, который работает в фоновом режиме, не блокируя основной поток (python), а использование очереди вызывает блокировку основного потока?

Я создаю приложение с помощью Django, есть функция (webasto_function), которая должна выполнять тяжелую обработку, эта же функция содержит приложение plotly dash (макет приложения и все такое), поэтому, как обычно, эта функция должна возвращать компонент dash. В моем основном коде я вызываю свою функцию (webasto_function) и когда результаты готовы, я перенаправляю на HTML-страницу, чтобы показать результаты. Как я уже сказал, эта функция очень тяжелая, поэтому я хочу создать поток, который будет обрабатывать эту функцию и работать в фоновом режиме, в то время как я смогу продолжать использовать другие функции моего приложения. И когда (webasto_function) завершается, перенаправить меня на страницу результатов. Для этого я создал отдельный поток (под названием p) для обработки функции webasto_function, используя очередь, я использовал очередь для хранения переменной флага, которая говорит, когда функция webasto_function завершается. И моя главная функция всегда проверяет, пуста ли очередь или нет, если пуста, то она ждет. В противном случае, если в очереди найдено значение (что указывает на то, что функция уже завершилась), она перенаправляет меня на HTML-страницу результатов. Функция делает то, что от нее ожидается, однако, моя проблема в том, что когда поток, отвечающий за реализацию (webasto_function), обрабатывается, он блокирует основной поток, и я не могу исследовать другие возможности приложения, пока обработка не завершится.

Другими словами, либо поток не реализован в фоне, что блокирует основной поток, либо очередь вызывает проблему, знает ли кто-нибудь, как с этим справиться.

def read_webasto_csv(request):
    if request.method == 'POST':
        values_from_user = request.POST.getlist('seuil_vit')[0]
    
        q = multiprocessing.Queue()
        p = threading.Thread(target=webasto_function, args=(values_from_user, request, q), daemon=True,name="Thread_webasto")
        p.start()
        print("Process Started Successfully")

        start = time.time()
        while True:
            time.sleep(1)  
            end = time.time()
            print("Time Running Webasto function " , f'time: {end - start:.1f}', end='\r')

                if q.empty():  
                   print("Queue is still empty, just wait.")
                   continue
                else:
                    print("The Background Process has finished and Prepared the results successfully")
                    print("The queue variable value is: ", q.get())
                    return redirect(results_webasto)
               

Я уверен, что вы понимаете, что невозможно дать правильное предложение, не зная точно, что происходит в этом зловещем webasto_function. Поэтому я могу дать только общие рекомендации.

Прежде всего, если вы еще не знаете об этом, вам следует прочитать о GIL, что делает Python... скажем так особенным в отношении потоков. Это то, что часто ставит в тупик людей, пришедших из других языков и полагающих, что потоки работают так, как ожидается в Python. Это не так.

В зависимости от того, что именно вы хотите сделать, вы можете пойти (по крайней мере) двумя путями: асинхронный код (который Django уже поддерживает) или многопроцессорная реализация, подобная той, что у вас уже есть. Оба этих варианта уже многократно обсуждались и сравнивались с потоковой обработкой в мельчайших подробностях на этом сайте и в других местах, поэтому я не буду тратить ваше время здесь.

Вернуться на верх