Неблокирующий запуск параллельных сопрограмм в Python

Предположим, что вы хотите найти «столбец» в «Таблице», и вы хотите, чтобы поиск в insensstive. Лучший и эффективный способ: ниже

//create empty JSON Object
mycolumn = {};

//check if column has valid value
if(column) {
    mycolumn.column = {$regex: new RegExp(column), $options: "i"};
}
Table.find(mycolumn);

Выше кода просто добавляет ваше значение поиска как RegEx и выполняется поиск с критериями insensitve, установленными с опцией «i».

Все лучший.

0
задан Maxim Blumental 18 January 2019 в 13:53
поделиться

2 ответа

Второй пункт вашего вопроса можно получить, запустив asyncio в отдельной теме и используя asyncio.run_coroutine_threadsafe для планирования сопрограмм. Например:

class FibonacciCalculatorAsync:
    def __init__(self):
        self.pool = ThreadPoolExecutor(max_workers=2)
        self.loop = asyncio.get_event_loop()

    @staticmethod
    def calculate_sync(n):
        print(f"started n={n}")
        return fibonacci(n)

    async def calculate(self, n):
        result = await self.loop.run_in_executor(self.pool, self.calculate_sync, n)
        print(result)

    def run(self, n):
        asyncio.run_coroutine_threadsafe(self.calculate(n), self.loop)

    def start_loop(self):
        thr = threading.Thread(target=self.loop.run_forever)
        thr.daemon = True
        thr.start()


if __name__ == '__main__':
    calculator = FibonacciCalculatorAsync()
    calculator.start_loop()
    calculator.run(35)
    calculator.run(32)
    print("initial thread can continue its work")
    calculator.run(10)
    time.sleep(1)
0
ответ дан user4815162342 18 January 2019 в 13:53
поделиться

loop.run_forever() действительно будет работать вечно, даже если внутри нет задач. Хорошей новостью является то, что вам не нужна эта функция. Чтобы дождаться завершения ваших вычислений, используйте asyncio.gather:

class FibonacciCalculatorAsync:

    def __init__(self):
        self.pool = ThreadPoolExecutor(max_workers=2)
        # self.loop = asyncio.get_event_loop()

    ...

    async def calculate(self, n):
        loop = asyncio.get_running_loop()
        result = await loop.run_in_executor(self.pool, self.calculate_sync, n)
        print(result)


async def main():
    calculator = FibonacciCalculatorAsync()
    fib_35 = asyncio.ensure_future(calculator.run(35))
    fib_32 = asyncio.ensure_future(calculator.run(32))

    print("initial thread can continue its work")
    ...

    # demand fibonaccy computation has ended
    await asyncio.gather(fib_35, fib_32)


if __name__ == '__main__':
    asyncio.run(main())

Обратите внимание, как обрабатывается цикл - я изменил несколько вещей. Если вы начнете использовать asyncio, я бы порекомендовал иметь один цикл для всех вещей вместо того, чтобы создавать циклы для более детальной задачи. При таком подходе вы получаете все асинхронные навороты для обработки и синхронизации задач.

Кроме того, из-за GIL невозможно распараллелить чистый код без ввода-вывода Python в ThreadPoolExecutor. Помните об этом и в таких случаях предпочитайте исполнителя пула процессов.

0
ответ дан Vovanrock2002 18 January 2019 в 13:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: