提示:.
是对 early versions of CFront 附带的旧协作式多任务库的引用(您也可以在该页面下载)。
如果您阅读论文“A Set of C++ Classes for Co-routine Style Programming”,事情会变得更有意义。
补充一点:
我还不够老,无法使用任务库。但是,我知道 C++ 是在 Stroustrup 在 Simula 中编写了一个模拟后设计的,该模拟具有许多与任务库相同的属性,所以我一直对此感到好奇。
如果我要实现书中的练习,我可能会这样做(请注意,我没有测试过这段代码,甚至没有尝试编译它):
class Scheduler {
std::list<*ITask> tasks;
public:
void run()
{
while (1) // or at least until some message is sent to stop running
for (std::list<*ITask>::iterator itor = tasks.begin()
, std::list<*ITask>::iterator end = tasks.end()
; itor != end
; ++itor)
(*itor)->run(); // yes, two dereferences
}
void add_task(ITask* task)
{
tasks.push_back(task);
}
};
struct ITask {
virtual ~ITask() { }
virtual void run() = 0;
};
我知道人们会不同意我的某些选择。例如,为接口使用结构;但是结构具有从它们继承的行为默认是公共的(从类继承默认是私有的),并且我看不到从接口私有继承的任何价值,那么为什么不将公共继承设为默认值呢?
这个想法是调用 ITask::run() 将阻塞调度程序,直到任务到达可以中断的点,此时任务将从 run 方法返回,并等待调度程序调用再次运行以继续。 “cooperative multitasking”中的“cooperative”是指“任务说什么时候可以中断”(“coroutine”通常表示“cooperative multitasking”)。一个简单的任务可能只在它的 run() 方法中做一件事,一个更复杂的任务可能会实现一个状态机,并且可能使用它的 run() 方法来确定对象当前处于什么状态,并根据它调用其他方法在那个状态。任务必须偶尔放弃控制才能使其工作,因为这就是“合作多任务”的定义。这也是所有现代操作系统不使用协作多任务处理的原因。
此实现不 (1) 遵循公平调度(可能会在任务的 run() 方法中保持运行的时钟滴答总数,并跳过相对于其他任务使用过多时间的任务,直到其他任务“赶上up"),(2) 允许删除任务,甚至 (3) 允许停止调度程序。
至于任务之间的通信,您可以考虑查看 Plan 9's libtask 或 Rob Pike's newsqueak 以获得灵感(“Newsqueak 的 UNIX 实现”下载包括一篇论文“Newsqueak 的实现”,该论文讨论了在一个有趣的虚拟机器)。
但我相信这是 Stroustrup 心目中的基本骨架。