事件驱动的模拟类

事件驱动的模拟类

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

问题描述

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

我不知道这是什么要求。任务是一个单独的线程吗? (据我所知,不可能创建一个新的线程没有系统调用,因为这是一本关于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)允许任务被移除,或者甚至允许



对于任务之间的通信,您可以考虑查看或的灵感(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:

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.

解决方案

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.

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

08-12 01:28