asyncio文档明确指出,asyncio代码不应直接调用阻塞代码,还指定了使用异步代码运行阻塞代码的方法:
不应直接调用阻塞(CPU绑定)代码。例如,如果函数执行CPU密集型计算1秒,则所有并发异步IO任务和IO操作将延迟1秒。
可以使用执行器在不同的线程中甚至在不同的进程中运行任务,以避免事件循环阻塞OS线程。
然而,这个描述对于在什么时候应该使用执行器不是很具体。很明显,“1秒钟的CPU密集型计算”是个问题,但是0.1秒会是个问题吗?还是0.01秒?
这些文档还提供了示例
def cpu_bound():
return sum(i * i for i in range(10 ** 7))
作为在执行器中运行的东西(运行不到一秒钟)。
(虽然他们可能会使用这个作为使用线程vs进程的例子,但它仍然是我的意思的一个例子——如果它是范围(10**6)
,等等,我会在执行器中运行它吗?)
在这一答复中,有人指出:
大多数标准库由常规的“阻塞”函数和类定义组成。他们工作很快,所以即使他们“阻止”,他们也会在合理的时间内回来。
...
标准库函数和方法的加载速度很快,为什么要在单独的线程中运行str.splitlines()
或urllib.parse.quote()
,而只执行代码并完成它会快得多?
但什么才算“合理时间”?我什么时候才能“执行代码并完成它”?
我的问题是:
您如何确定需要执行人?
这个问题不是asyncio独有的。据我所知,还没有人提出一个精确的标准。
当前的做法与其他与性能相关的决策相同:通过结合常识和分析来确定。根据常识,可以在事件循环线程中调用urllib.parse.quote()
,但使用BeautifulSoup解析任意大小的HTML文档可能不行。根据经验,协同程序可以包含您在Twisted这样的经典异步系统中轻松放置在回调中的代码。
如果你的代码“阻塞”太久,实际会发生什么?有什么迹象表明是这样的呢?
您会注意到延迟增加,吞吐量降低。
程序的预期延迟可能是决定何时开始使用执行程序的因素。还要注意,将某样东西交给执行者有其不可忽视的开销,所以你不想为所有事情都这样做,如果你为非常快的事情(例如归结为几个判决查找)。
我有一个并发HashMap,我在其中执行以下操作: 我的问题是——是否没有必要做额外的 检查synschronized块内部,以便其他线程不会初始化相同的hashmap值? 也许检查是必要的,但我做错了?我在做的事情似乎有点愚蠢,但我认为这是必要的。
问题内容: 我知道他们两个都禁用了Nagle的算法。 我什么时候应该/不应该使用它们中的每一个? 问题答案: 首先,不是所有人都禁用Nagle的算法。 Nagle的算法用于减少有线中更多的小型网络数据包。该算法是:如果数据小于限制(通常是MSS),请等待直到收到先前发送的数据包的ACK,同时累积用户的数据。然后发送累积的数据。 这将对telnet等应用程序有所帮助。但是,在发送流数据时,等待A
问题内容: 在该类中,有两个字符串,和。 有什么不同?我什么时候应该使用另一个? 问题答案: 如果你的意思是和则: 用于在文件路径列表中分隔各个文件路径。考虑在上的环境变量。您使用a分隔文件路径,因此在上将是;。 是或用于拆分到特定文件的路径。例如在上,或
hibernate文档中说:“如果您希望利用运行时代理生成,那么至少应该使用包可见性来定义构造函数。”。我在hibernate文档中读到,hibernate可以增强字节码而不是代理创建(hibernate 5.x)。在任何情况下,它都可以用这种新方法代替代理创建?在哪些情况下需要生成运行时代理?
问题内容: 有什么区别?什么时候应该使用容量为1的对抗? 问题答案: SynchronousQueue更像是一个传递,而LinkedBlockingQueue仅允许单个元素。区别在于对SynchronousQueue的put()调用直到有相应的take()调用 才返回 ,但LinkedBlockingQueue的大小为1,则put()调用(对空队列)将立即返回。 我不能说自己曾经直接使用过Sync
问题内容: 我对使用和翻译有疑问。我了解到,在模型中,我应该使用。但是还有其他地方我也应该使用吗?表单定义呢?它们之间是否存在性能差异? 编辑: 还有一件事。有时候,代替被使用。正如文档所述,仅在将字符串显示给用户之前,才将字符串标记为要翻译,并在可能的最新情况下进行翻译,但是我在这里有点困惑,这与功能相似吗?我仍然很难决定在模型和表格中应该使用哪个。 问题答案: ugettext() 与 uge