2017-07-31 51 views
1

在同一个python项目中使用asyncio和线程是否合理,以便代码在不同的线程中运行,其中一些asyncio用于获取顺序查找的异步活动代码?使用asyncio和线程

或会试图做到这一点意味着我错过了关于使用线程或asyncio的一些基本概念?

+0

相关:[线程](http://asyncio.readthedocs.io/en/latest/threads.html)来自[asyncio用户文档](http://asyncio.readthedocs.io/en/latest/index的.html)。 – Vincent

回答

1

确定它可能是有道理的。

异步代码原则上在同一个线程中运行一堆例程。

这意味着此刻一个例程必须等待输入或输出(I/O),将暂时停止该例程并简单地开始处理另一个例程,直到遇到一个等待在那里,等等

多线程代码原则上在您机器的不同核心上运行,同时

在同一个程序中使用它们可能会很有意义。使用asyncio为了在等待I/O时继续处理。例如,使用多线程可以在程序的另一部分中并行执行大量计算。

0

我不明白你在问什么(关于“按顺序查看异步活动代码”的一部分),但由于没有答案,我会写一些想法。

让我们来谈谈为什么我们需要asyncio/threads。想象一下,我们有一个任务来提出两个请求。

  1. 如果我们将使用普通的一个线程非异步代码,只是我们 选择是使请求一个URL,而且只要完成后 - 为 另:

    request(url1) 
    request(url2) 
    

    问题这里是我们做的工作效率低下:每个功能在执行的大部分时间都不会等待网络结果。如果我们以某种方式能够使用CPU进行第二次请求,而第一次使用CPU而不需要它,那将会很酷。

  2. 这个问题可以通过在不同的线程中运行的功能来解决(通常可以解决):

    with ThreadPoolExecutor(max_workers=2) as e: 
        e.submit(request, url1) 
        e.submit(request, url2) 
    

    我们会得到更快的结果这样。当第一个请求被网络阻塞时,CPU将能够为另一个线程中的第二个请求做一些有用的事情。然而,这不是理想的解决方案:线程之间的切换具有一定的成本,执行流程比第一个示例更复杂。

    应该有更好的方法。

  3. 使用一个功能空闲时间开始执行另一个功能是一般什么ASYNCIO:

    await asyncio.gather(
        async_request(url1), 
        async_request(url2), 
    ) 
    

    事件循环管理执行流程:当第一个协程到达一些I/O操作和CPU可以用来在别处做工作,第二个协程开始。稍后的事件循环返回,以保持第一个协程的执行。

    我们得到“并行”请求和清晰可理解的代码。由于我们在单线程中并行化,所以我们不需要另一个线程。

实际上,当我们使用asyncio线程仍然可以是有用的。如果我们愿意为他们支付,他们可以help我们投同步I/O功能,非常快速异步:

async def async_request(url): 
    loop = asyncio.get_event_loop() 
    return (await loop.run_in_executor(None, request, url)) 

但同样,这是可选的,我们通常可以找到模块发出请求(和其他I/O任务)异步无线程。

当线程在异步程序中很有用时,我没有面对任何其他任务。

+0

这是在算法交易的情况下,我使用Intectivity经纪人的Python TWS API(如果我理解正确的话)在除主代码之外的其他线程上进行回调。我是python的新手,并试图找出在环境中做东西的最佳方式,并且混淆了多个线程和asyncIO(在单个线程中运行)之间的关系。 – epeleg