事件驱动的模拟类 [英] Event-driven simulation class

查看:152
本文介绍了事件驱动的模拟类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过Bjarne Stroustrup的C ++编程语言中的一些练习。我对第12章结尾的问题11感到困惑:

(* 5)设计和实现一个用于编写事件驱动模拟的库。提示:< task.h> ;. ...类任务的一个对象应该能够保存它的状态,并且恢复该状态,以便它可以作为协同程序运行。特定任务可以定义为从任务派生的类的对象。要由任务执行的程序可以被定义为虚拟函数。 ...应该有一个调度器实现虚拟时间的概念。 ...任务需要沟通。为此设计类队列。 ...

我不知道这是什么要求。任务是一个单独的线程吗? (据我所知,不可能创建一个新的线程没有系统调用,因为这是一本关于C + +的书,我不相信这是意图)。没有中断,如何可以启动和停止运行功能?我认为这将涉及忙等待(这就是说,不断循环和检查条件),虽然我不能看到这可以应用于可能不会终止一段时间的函数(如果它包含一个无限循环,例如)



编辑:请参阅下面的详细信息。

解决方案


提示:< task.h>。


引用 CFront的早期版本附带的旧协作式多任务库(您可以



如果您阅读了这篇文章一组用于协同例程样式编程的C ++类事情会更有意义。






添加一个位:



我不是一个老的程序员使用任务库。但是,我知道C ++是在Stroustrup在Simula中编写了一个具有许多与任务库相同属性的模拟之后设计的,所以我一直很好奇它。



如果我从书中实现练习,我可能这样做(请注意,我没有测试这个代码,甚至尝试编译):

  class Scheduler {
std :: list< * ITask>任务;
public:
void run()
{
while(1)//或至少直到发送一些消息停止运行
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;
};

我知道人们会不同意我的一些选择。例如,使用接口的struct;但结构体的行为是从它们继承默认情况下是公共的(默认情况下从类继承是私有的),并且我没有看到从接口私有继承的任何值,所以为什么不使公共继承默认? p>

这个想法是调用ITask :: run()会阻塞调度器,直到任务到达可以被中断的点,此时任务将从运行方法,并等待调度程序调用再次运行以继续。 协作多任务中的协同是指任务可以中断时(协同通常意味着协作多任务)。一个简单的任务只能在其run()方法中做一件事,一个更复杂的任务可以实现一个状态机,并且可以使用它的run()方法来确定对象当前处于什么状态,并调用其他方法对该状态。任务必须暂时放弃控制一次,因为这是协作多任务的定义。这也是所有现代操作系统不使用协作多任务的原因。



此实现不会(1)遵循公平调度(可能保持总时钟滴答花在任务的run()方法中,以及跳过相对于其他任务使用太多时间的任务,直到其他任务赶上),(2)允许任务被移除,或者甚至允许



对于任务之间的通信,您可以考虑查看计划9的libtask Rob Pike的新闻稿的灵感(UNIX实施Newsqueak下载包括一篇论文,The Implementation of Newsqueak,讨论在一个有趣的虚拟机中传递消息)。



但我相信这是Stroustrup的基本框架。


I am working through some of the exercises in The C++ Programming Language by Bjarne Stroustrup. I am confused by problem 11 at the end of Chapter 12:

(*5) Design and implement a library for writing event-driven simulations. Hint: <task.h>. ... An object of class task should be able to save its state and to have that state restored so that it can operate as a coroutine. Specific tasks can be defined as objects of classes derived from task. The program to be executed by a task might be defined as a virtual function. ... There should be a scheduler implementing a concept of virtual time. ... The tasks will need to communicate. Design a class queue for that. ...

I am not sure exactly what this is asking for. Is a task a separate thread? (As far as I know it is not possible to create a new thread without system calls, and since this is a book about C++ I do not believe that is the intent.) Without interrupts, how is it possible to start and stop a running function? I assume this would involve busy waiting (which is to say, continually loop and check a condition) although I cannot see how that could be applied to a function that might not terminate for some time (if it contains an infinite loop, for example).

EDIT: Please see my post below with more information.

解决方案

Hint: <task.h>.

is a reference to an old cooperative multi-tasking library that shipped with early versions of CFront (you can also download at that page).

If you read the paper "A Set of C++ Classes for Co-routine Style Programming" things will make a lot more sense.


Adding a bit:

I'm not an old enough programmer to have used the task library. However, I know that C++ was designed after Stroustrup wrote a simulation in Simula that had many of the same properties as the task library, so I've always been curious about it.

If I were to implement the exercise from the book, I would probably do it like this (please note, I haven't tested this code or even tried to compile it):

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;
};

I know people will disagree with some of my choices. For instance, using a struct for the interface; but structs have the behavior that inheriting from them is public by default (where inheriting from classes is private by default), and I don't see any value in inheriting privately from an interface, so why not make public inheritance the default?

The idea is that calls to ITask::run() will block the scheduler until the task arrives at a point where it can be interrupted, at which point the task will return from the run method, and wait until the scheduler calls run again to continue. The "cooperative" in "cooperative multitasking" means "tasks say when they can be interrupted" ("coroutine" usually means "cooperative multitasking"). A simple task may only do one thing in its run() method, a more complex task may implement a state machine, and may use its run() method to figure out what state the object is currently in and make calls to other methods based on that state. The tasks must relinquish control once in a while for this to work, because that is the definition of "cooperative multitasking." It's also the reason why all modern operating systems don't use cooperative multitasking.

This implementation does not (1) follow fair scheduling (maybe keeping a running total of clock ticks spent in in task's run() method, and skipping tasks that have used too much time relative to the others until the other tasks "catch up"), (2) allow for tasks to be removed, or even (3) allow for the scheduler to be stopped.

As for communicating between tasks, you may consider looking at Plan 9's libtask or Rob Pike's newsqueak for inspiration (the "UNIX implementation of Newsqueak" download includes a paper, "The Implementation of Newsqueak" that discusses message passing in an interesting virtual machine).

But I believe this is the basic skeleton Stroustrup had in mind.

这篇关于事件驱动的模拟类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆