Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我什么时候需要为异步代码使用执行器?如果我不';t(但应该)?_Python_Python 3.x_Python Asyncio - Fatal编程技术网

Python 我什么时候需要为异步代码使用执行器?如果我不';t(但应该)?

Python 我什么时候需要为异步代码使用执行器?如果我不';t(但应该)?,python,python-3.x,python-asyncio,Python,Python 3.x,Python Asyncio,说明了异步IO代码不应直接调用阻塞代码,还指定了使用异步代码运行阻塞代码的方法: 不应直接调用阻塞(CPU绑定)代码。例如,如果函数执行CPU密集型计算1秒,则所有并发异步IO任务和IO操作将延迟1秒 可以使用执行器在不同的线程中甚至在不同的进程中运行任务,以避免事件循环阻塞OS线程 然而,这个描述并不是非常具体的关于在什么时候应该使用执行者。很明显,“1秒的CPU密集型计算”会是个问题,但0.1s会是个问题吗?还是0.01秒 这些文件还提供了 作为在执行器中运行的东西(运行时间不到一秒钟) (

说明了异步IO代码不应直接调用阻塞代码,还指定了使用异步代码运行阻塞代码的方法:

不应直接调用阻塞(CPU绑定)代码。例如,如果函数执行CPU密集型计算1秒,则所有并发异步IO任务和IO操作将延迟1秒

可以使用执行器在不同的线程中甚至在不同的进程中运行任务,以避免事件循环阻塞OS线程

然而,这个描述并不是非常具体的关于在什么时候应该使用执行者。很明显,“1秒的CPU密集型计算”会是个问题,但0.1s会是个问题吗?还是0.01秒

这些文件还提供了

作为在执行器中运行的东西(运行时间不到一秒钟)

(虽然他们可能会将此作为使用线程与进程的示例,但它仍然是我的意思的示例——如果它是
范围(10**6)
,我会在执行器中运行它吗


对此,有人说:

大多数标准库由常规的“阻塞”函数和类定义组成。他们工作很快,所以即使他们“阻止”,他们也会在合理的时间内回来

标准库函数和方法的加载速度很快,为什么要在单独的线程中运行
str.splitlines()
urllib.parse.quote()
,而只执行代码并完成它会快得多

但什么才算“合理时间”?我什么时候才能“执行代码并完成它”


我的问题是:

  • 您如何确定需要执行人
  • 如果代码“阻塞”太长,实际会发生什么?这种情况的迹象是什么
  • 您如何确定需要执行人

    这个问题不是asyncio独有的。据我所知,还没有人提出一个精确的标准

    当前的做法与其他与性能相关的决策相同:通过结合常识和分析来确定。根据常识,可以在事件循环线程中调用
    urllib.parse.quote()
    ,但使用BeautifulSoup解析任意大小的HTML文档可能不行。根据经验,协同程序可以包含您在Twisted这样的经典异步系统中轻松放置在回调中的代码

    如果代码“阻塞”太长,实际会发生什么?这种情况的迹象是什么

    您会注意到延迟增加,吞吐量降低


    程序的预期延迟可能是决定何时开始使用执行器的因素。还要注意的是,将某件事情交给执行者有其不可忽略的开销,因此您不希望对所有事情都这样做,而且如果您对速度非常快的事情(例如归结为两个dict查找的代码)这样做,实际上会使事情变慢.

    合理的时间意味着它不会因为太长而阻止其他线程运行(需要这样做)。一次只能运行一个线程,因为它们在Python中通常不会并发运行。当您超过限制时,代码将停止执行您试图完成的任何操作-没有硬性规定。@martineau Stephen的问题是关于asyncio的,它是真正的单线程,而不仅仅是由GIL序列化的。正如您所指出的,对于多线程,没有并行性——但您至少可以依靠Python偶尔在线程之间切换。持有GIL的线程将遇到阻塞功能,该功能将立即释放GIL,或者在之后释放GIL。Asyncio是协作性的,不给予这样的承诺:不等待任何东西而运行的代码可以无限期地阻止所有其他Asyncio任务。
    def cpu_bound():
        return sum(i * i for i in range(10 ** 7))