python asyncio имеет проблемы с асинхронным запуском двух бесконечных функций - PullRequest
1 голос
/ 20 июня 2020

Итак, я пытался запустить две функции одновременно, но одна, кажется, никогда не работает, пока я не остановлю другую. Первая функция предназначена для отправки электронного письма каждые 30 секунд (функция проверена сама по себе, и она работает), вторая - для печати простого оператора каждые 5 секунд. Итак, после каждых 6 заявлений "Hello Worlds", которые я вижу, я должен получать электронное письмо. Тем не менее, я никогда не получаю электронное письмо, если я не использую что-то в функции запуска, чтобы остановить его, например, «конец через 10 секунд». Я хочу sh, чтобы обе функции продолжались бесконечно (без сбоев, если это возможно). Любая помощь приветствуется.

async def timer():
    now = time.time()
    end = now + 30
    #sendmail(name, filepath + "\\" + name, receiver)
    while True:
        if time.time() >= end:
            sendmail(name, filepath + "\\" + name, receiver)
            now = time.time()
            end = now + 30

async def runs():
    while True:
        print("Hello World")
        time.sleep(5)


loop = asyncio.get_event_loop()
loop.create_task(runs())
loop.create_task(timer())
loop.run_forever()

Также, если кто-нибудь сможет выполнить задачу с помощью модуля многопроцессорности или многопоточности, мне было бы интересно посмотреть, как это делается, поскольку я пытался и потерпел неудачу с обоими. образец того, что я пробовал:

t1 = threading.Thread(target=timer)
t2 = threading.Thread(target=runs)
t1.start()
t2.start()

Ответы [ 2 ]

3 голосов
/ 20 июня 2020
Сопрограммы

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

async def timer():
    while True:
        await asyncio.sleep(30)
        sendmail(name, filepath + "\\" + name, receiver)

async def runs():
    while True:
        print("Hello World")
        await asyncio.sleep(5)

async def main():
    await asyncio.gather(timer(), runs())

asyncio.run(main())

Примечательно, что не используйте time.sleep - это блокирует текущую сопрограмму, а также событие l oop и все остальные сопрограммы.

1 голос
/ 20 июня 2020

Вы можете использовать await asycio.sleep() для asyn c wait

import asyncio


async def timer():
    while True:
        
        print("email sent")
        await asyncio.sleep(30)


async def runs():
    while True:
        print("Hello World")
        await asyncio.sleep(5)

loop = asyncio.get_event_loop()
loop.create_task(timer())
loop.create_task(runs())
loop.run_forever()
...