的概念 协程 听起来很有趣,但我不知道,这在真正的生产环境中是否有意义?协程的哪些用例可以像其他方法一样更优雅、更简单或更有效地解决?

有帮助吗?

解决方案

真正的协同程序需要您的工具支持 - 它们需要由编译器实现并由底层框架支持。

使用<!> quot; yield return <!>来找到Coroutines的一个真实世界示例; C#2.0中提供的关键字,它允许您编写一个返回多个循环值的方法。

<!> quot; yield return <!> quot;但是确实有一些限制 - 实现使用一个辅助类来捕获状态,它只支持一个特定的coroutine作为生成器(迭代器)。

在更一般的情况下,Coroutines的优势在于它们使某些基于状态的计算更容易表达和更容易理解 - 将状态机实现为一组协程可以比更常见的方法更优雅即可。但是,这样做需要C#或Java中尚不存在的支持和工具。

其他提示

描述协程的一些好答案。

但是对于实际的用例。拿一个Web服务器。它有多个同时连接,它想安排读写所有连接。

这可以使用协程来实现。每个连接都是一个读取/写入少量数据的协程,然后<!> quot; yield <!> quot;控制调度程序,它循环到下一个协同程序(它做同样的事情),循环遍历所有可用的连接。

很多,例如:

grep TODO *.c *.h | wc -l

上面的管道正是一个协程:grep命令生成一系列到达缓冲区的行,wc命令<!>“将它们吃掉<!>”;如果缓冲区填充,则<=> <!>“阻止<!>”;直到缓冲区清空,如果缓冲区为空,<=>命令等待新输入。

关于协同程序的事情是它们现在最常用于更多约束模式,如提到的Python生成器,或者作为管道。

如果您想更多地了解它们,请参阅维基百科的文章,特别是关于协同程序迭代器

我知道问题被问到这已经差不多5年了,但是我很惊讶没有人提到游戏的用例,其中协同程序被大量用于实际计算时间。

为了在游戏中保持一致的帧速率,假设为60 fps,每帧中执行代码大约需要16.6ms。这包括物理模拟,输入处理,绘图/绘画。

让我们说你的方法是在每一帧中执行的。如果你的方法花费很长时间并最终跨越多个帧,你将在游戏循环中错开其余的计算,这导致用户看到<!>“jank <!>”; (帧速率突然下降)。

你可以做什么协同程序以某种方式对这个计算进行时间切片,以便它在每一帧中运行一点点。

为了实现这一点,协同程序基本上允许该方法<!> quot; yield <!> quot;计算回到<!>“;调用者<!>”; (在这种情况下是游戏循环),以便下次调用该方法时,它将从中断处继续。

协程可用于实现生产者/消费者模式。

例如,Python在一个名为生成器的语言功能中引入了协同程序,旨在简化迭代器的实现。

它们对于实现协作式多任务处理也很有用,其中每个任务都是一个可以产生调度程序/反应堆的协程。

当系统有两个或多个代码时,协程会很有用,其中最自然的表示形式是一系列连续的步骤,需要大量的等待。

例如,考虑一个具有LCD和键盘用户界面和调制解调器的设备,它需要使用调制解调器定期调用和报告其状态,而与键盘上的用户正在做什么无关。编写用户界面的最好方法可能是使用<!> quot; input_numeric_value(<!> amp; CONV_SPEED_FORMAT,<!> amp; conveyor_speed)等函数; <!> quot;当用户输入值时将返回,并且处理通信的最佳方式可以是使用诸如<!>“wait_for_carrier(); <!>”之类的函数;当装置连接或确定它不会返回时,它将返回。

如果没有协同程序,则必须使用状态机来实现UI子系统或调制解调器子系统。使用协程可以使两个子系统以最自然的方式编写。请注意,重要的是,如果没有将事物放入<!>“一致的<!>”中,那么子系统都不会很长。 state并调用yield(),也不调用yield()而不将东西放入<!> quot; consistent <!> quot;首先说明,但通常不难达到这些限制。

请注意,虽然可以使用完整的多任务处理,但只要共享状态发生变化,就需要在整个地方使用锁。由于协程切换器除了在yield()调用之外不会切换任何东西,所以任何例程都可以自由地改变共享状态,只要它确保在下一次产生之前按顺序排列所有内容,并为其他例程改变状态做好准备< !> QUOT;在<> QUOT!; yield()。

作为生产者/消费者系列中更具体的示例,像不起眼的批量报告程序这样简单的东西实际上可以使用协同例程。

该示例的关键提示是需要进行一项重要的工作来消耗输入数据(例如解析数据或累积帐户的费用和付款),以及产生输出的重要工作。当你具备以下特征时:

  • 如果您可以在不同的地方“发出”工作单元,那么组织/理解输入端代码就很容易。
  • 如果输出端代码可以“抓取”嵌套控制结构中的下一个工作单元,那么组织/理解输出端代码同样很容易。

那么协程和队列都是可供您使用的好技术。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top