在一个有多个协同程序的环境中,实现优先级是否合理



我正在读一些Lua的书,我正在考虑将一些遗留的(写得不好的)C代码迁移到Lua和C的混合中。

然而,这个遗留代码使用线程来处理一些关键任务(基本上是音频/视频流),同时也有一些简单的任务需要注意(用户界面)。据我所知,Lua并不直接支持线程,它促进了协程的使用。

在这种情况下迁移到基于协同程序的环境是否明智?在我的脑海中,我可以想象一个调度器,它总是在每次尝试恢复最不重要的协程之间,首先尝试恢复高优先级的协程。由于我没有这方面的经验,我在这里问。

编辑

Nicol Bolas询问了更多细节。

这是一个实时应用程序。我不能承受处理一些事件的大延迟,比如准备处理的新视频帧。以前的C程序使用线程和回调来实现这一点。例如,在出现新帧时,会调用回调,并准备处理数据(回调作为生产者,视频线程作为消费者)。

我还没有想过如何处理回调(也许我会用C保存它们,并使用一些互斥来更新Lua代码的数据),但我怀疑这种使用上述工具的设置是否适用于这种问题,以及是否有人有一些例子或故事想要分享。

没有理由不尝试。游戏是为了创建一个合适的调度程序,并确保你的例程在屈服之前不会花费太多时间。

这将有多困难取决于您的代码,但调度程序可能非常简单——通过优先级或简单计时器(如果上次运行important_routine的时间>N毫秒,则运行important_routine)。

您在yield方面有一些优势,它确实使同步变得容易。

简单地说,你应该证明它,看看它是否对你足够有效。玩一玩,你应该很快知道这是否真的对你有用,从声音上看,你的调度器可能并不复杂。没有理由让它成为通用的,保持简单并专注于你正在做的任务,然后循环使用"通用的",或者从操作系统的教科书中提取一些随机的调度程序。

您可能可以这样做;据我所知,你面临的主要挑战将是决定你能付出的最短时间,以及如何保证这段时间不会被超过。

例如,假设您的流媒体可以容忍高达10ms的延迟。这意味着你的UI操作必须被分割成不超过10ms的块。如果你继续你的UI协同程序在文件中进行搜索,并且你需要读取一个文件,结果文件很大,读取时间超过10ms,该怎么办?直到UI协同程序将控制权交还给调度器,调度器才能恢复流式协同程序。这只意味着您需要非常小心地考虑UI可以执行的所有操作,以及如何确保所有操作都遵守您为它们设置的时间限制。

在抢占式多任务中,调度器会处理这一问题(但它也有自己的缺点),但在协同程序的情况下,UI逻辑需要处理这一点。有一些lua库具有一些类似的逻辑(例如,copas做了一些类似于您可能需要的使用超时的套接字的事情)。

比较回调和协同程序,我开始越来越喜欢协同程序的方法。它们的功能可能是等效的,但基于协程的代码比基于回调的代码更容易阅读(在许多情况下也更容易编写)(严格地说,在我看来)。

相关内容

最新更新