python asyncio: ждать в сопрограмме промежуточного результата другой сопрограммы - PullRequest
0 голосов
/ 24 апреля 2018

У меня есть 2 сопрограммы (co_A, co_B) в разных классах (class_A, class_B), которые регулярно вызываются планировщиком. В какое-то время во время выполнения co_B требуется результат, который co_A вычисляет во время его выполнения.

Я хотел бы сделать что-то вроде этого:

class class_A:
    async def co_A(self):

        # execute time consuming code

        # set result that co_B needs
        self.set_result(result)

        # execute more time consuming code

class class_B:
    async def co_B(self):

        # execute time consuming code

        # wait for result from co_A
        result = await class_A_instance.get_result()

        # execute more time consuming code

Мой подход состоит в том, чтобы иметь пустое Future в class_A, которое заполняется во время co_A и в co_B, ждать в цикле, пока не будет установлено Future:

class class_A:
    async def prepare(self):
        self.fut = asyncio.Future()

    async def co_A(self):

        # execute time consuming code

        # set result that co_B needs
        self.fut.set_result(result)

        # execute more time consuming code

class class_B:   
    async def co_B(self):

        # execute time consuming code

        # wait for result from co_A
        while not class_A_instance.fut.done():
            await asyncio.sleep(0)

        result = class_A_instance.fut.result()

        # execute more time consuming code

Есть ли лучший способ сделать это без необходимости спать в цикле, пока co_A не вычислит результат?

Ответы [ 2 ]

0 голосов
/ 24 апреля 2018

Я бы использовал Event класс для синхронизации сопрограмм. Подход @Mikhail на 100% верен, но не соответствует адресу, который вы хотели бы получить в середине co_A.

class A:
    def __init__(self):
        self.partially_ready = asyncio.Event()

    async def prepare(self):
        self.partially_ready.clear()

    async def co_A(self):   
        # execute time consuming code

        # set result that co_B needs
        self.partially_ready.set()
        # execute more time consuming code


class class_B:   
    async def co_B(self):

        # execute time consuming code

        # wait for result from co_A
        await A_instance.partially_ready.wait()
        # here A_instance finished some part you would like to wait
0 голосов
/ 24 апреля 2018

Идея будущего заключается в том, что вы можете ожидать его, как и в случае с сопрограммами, задачами и т. Д.

class class_B:   
    async def co_B(self):

        # execute time consuming code

        # wait for result from co_A
        result = await class_A_instance.fut

        # execute more time consuming code

См. Раздел «Что может сделать сопрограмма» здесь .

...