Я новичок в asyncio и пытаюсь запустить код блокировки в отдельном потоке с помощью loop.run_in_executor, но кажется, что не создаются новые потоки для запуска кода блокировки, и он все еще работает в основном потоке. Может кто-нибудь помочь мне понять, как я могу выполнить операцию блокировки в асинхронном режиме? Цените всю помощь.
Я попытался сделать async.sleep (), чтобы управление возвращалось основному потоку, но я не уверен, как это сделать, так как я уже вызвал библиотеку. loop.run_in_exeutor, похоже, не работает по какой-то причине.
async def get_xml(self, genome_key, query_string):
executor = concurrent.futures.ThreadPoolExecutor(max_workers=3)
loop = asyncio.get_event_loop()
log = logging.getLogger('run_blocking_tasks')
log.info('starting')
log.info('creating executor tasks')
blocking_tasks = loop.run_in_executor(executor, self.blocking_io, genome_key, query_string)
log.info('waiting for executor tasks')
completed = await asyncio.wait([blocking_tasks])
log.info('results: {!r}'.format(completed))
log.info('exiting')
Вот код блокировки:
def blocking_io(self, genome_key, query_string):
return NCBIWWW.qblast("blastn","nt",query_string,megablast=False,expect="1000",word_size="7",nucl_reward="1",nucl_penalty="-3",gapcosts="5 2",entrez_query=self.genome_key_dict[genome_key])
Функция get_xml вызывается так:
async def getMatchingLocations(self,query, loop):
r1 = self.get_max_alignment("nc_009899",query,loop)
r2 = await asyncio.gather(r1)
return r2
И функция getMatchingLocations вызывается из колбы следующим образом:
@application.route('/search',methods = ['POST'])
def getQueryResult():
q = request.form
myObj = Alignment_Check()
mLocations_s = loop.run_until_complete(myObj.getMatchingLocations(q.get("Name"), loop))
Вот пример вывода:
> Thread-1 run_blocking_tasks: starting
> Thread-1 run_blocking_tasks: creating executor tasks
> Thread-1 run_blocking_tasks: waiting for executor tasks
> Thread-1 asyncio: poll took 241953.000 ms: 1 events
> Thread-1 run_blocking_tasks: results: ({> created at ***}, set())
Thread-1 run_blocking_tasks: exiting
> As we can see that the thread too 241953.000 ms to complete and my application was doing nothing but sitting idle for that time.
> The expected behavior is that the blocking function should be executed in a separate thread and once it is done executing I should be able to update my application with the results.