Pregunta

Estoy trabajando en algunos de los ejercicios del lenguaje de programación C++ de Bjarne Stroustrup.Estoy confundido por el problema 11 al final del Capítulo 12:

(*5) Diseñar e implementar una biblioteca para escribir simulaciones basadas en eventos.Pista:<tarea.h>....Un objeto de tarea de clase debería poder guardar su estado y restaurarlo para que pueda operar como una rutina.Las tareas específicas se pueden definir como objetos de clases derivadas de la tarea.El programa que ejecutará una tarea podría definirse como una función virtual....Debería haber un programador que implemente un concepto de tiempo virtual....Las tareas deberán comunicarse.Diseñe una cola de clases para eso....

No estoy seguro exactamente de qué se pide esto.¿Es una tarea un hilo separado?(Hasta donde yo sé, no es posible crear un nuevo hilo sin llamadas al sistema, y ​​dado que este es un libro sobre C++, no creo que esa sea la intención). Sin interrupciones, ¿cómo es posible iniciar y detener un hilo en ejecución? ¿función?Supongo que esto implicaría una espera ocupada (es decir, realizar un bucle continuo y verificar una condición), aunque no veo cómo podría aplicarse eso a una función que podría no terminar durante algún tiempo (si contiene un bucle infinito, por ejemplo). .

EDITAR: Consulte mi publicación a continuación con más información.

¿Fue útil?

Solución

  

Consejo:.

es una referencia a una cooperativa antigua biblioteca multi-tarea que se envió con las primeras versiones de Cfront (también se puede descargar en la página).

Si usted lee el periódico " un conjunto de clases de C ++ Co-rutina de estilo de programación " cosas hará mucho más sentido.


Adición de un bit:

No soy un programador edad suficiente para haber utilizado la biblioteca de tareas. Sin embargo, sé que C ++ fue diseñado después BS escribió en una simulación Simula que tenía muchas de las mismas propiedades que la biblioteca de tareas, así que siempre he sentido curiosidad por él.

Si tuviera que poner en práctica el ejercicio del libro, probablemente lo haría así (tenga en cuenta, no he probado este código o incluso trató de compilar):

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

Sé que la gente no estará de acuerdo con algunas de mis opciones. Por ejemplo, utilizando una estructura para la interfaz; pero tienen estructuras que heredar el comportamiento de ellos es pública por defecto (donde la herencia de clases es privada por defecto), y yo no ven ningún valor en la herencia de forma privada desde una interfaz, ¿por qué no hacen pública la herencia predeterminada?

La idea es que las llamadas a iTask :: run () bloqueará el programador hasta que la tarea llega a un punto en el que se puede interrumpir, momento en el que la tarea volverá a partir del método de ejecución, y esperar hasta que las llamadas planificador correr de nuevo para continuar. La "cooperación" en "multitarea cooperativa" significa "tareas dicen cuando pueden ser interrumpidos" ( "co-rutina" generalmente significa "multitarea cooperativa"). Una tarea simple solamente puede hacer una cosa en su método run (), una tarea más compleja puede implementar una máquina de estados, y puede usar su método run () para averiguar en qué estado del objeto se encuentra actualmente en y hacer llamadas a otros métodos basados en ese estado. Las tareas debe ceder el control de vez en cuando para que esto funcione, porque esa es la definición de "multitarea cooperativa." Es también la razón por la cual todos los sistemas operativos modernos no utilizan multitarea cooperativa.

Esta aplicación no (1) sigue planificación equitativa (tal vez mantener un total acumulado de ticks de reloj que pasó en en ejecución de la tarea () método, y saltar tareas que ha tomado mucho tiempo en relación con los otros hasta que las otras tareas "captura up "), (2) permiten para las tareas a ser removidos, o incluso (3) permiten el planificador para ser detenido.

En cuanto a la comunicación entre tareas, puede considerar mirando de Plan 9 libtask o newsqueak de Rob Pike por la inspiración (la 'aplicación de UNIX Newsqueak' descarga incluye un documento, 'la implementación de Newsqueak' que trata sobre el paso de mensajes en una máquina virtual interesante).

Sin embargo, creo que este es el esqueleto básico BS tuvo en cuenta.

Otros consejos

Aquí está mi comprensión de una "simulación de eventos":

  • Un controlador maneja una cola de eventos, la programación de eventos que se produzcan en ciertos momentos, a continuación, ejecutar el evento superior en la cola.
  • Eventos OCUR instantáneamente a la hora programada. Por ejemplo, un evento de "movimiento" actualizaría la posición y el estado de una entidad en la simulación de tal manera que el vector de estado es válido en el momento actual de la simulación. Un evento de "sentido" tendría que asegurarse de que todos los estados son entidades en el momento actual, a continuación, utilizar algún modelo matemático para evaluar el funcionamiento de la entidad actual puede sentir las otras entidades. (Piense robots moverse en un tablero.)
  • Así, el tiempo avanza de forma discontinua, saltando de un evento a otro. Contrasta esto con una simulación por tiempo, donde el tiempo se mueve en pasos discretos y los estados todas las entidades se actualizan cada paso de tiempo (a la mayoría de los modelos de Simulink).
  • Eventos entonces pueden ocurrir en su tasa natural. Por lo general, no tiene sentido para volver a calcular todos los datos en la mejor tasa en la simulación.

Los más producción simulaciones por eventos se ejecutan en un solo hilo. Pueden ser complejo por su propia naturaleza, por lo que se intenta sincronizar una simulación multi-roscado tiende a añadir capas de complejidad exponencial. Dicho esto, hay un estándar para simulaciones militares multi-proceso llamado distributiva Simulación Interactiva (DIS) que utiliza mensajes TCP predefinidos para transmitir datos entre procesos.

EDIT: Es importante definir la diferencia entre el modelado y simulación. Un modelo es una representación matemática de un sistema o proceso. Una simulación se construye a partir de uno o más modelos que se ejecutan durante un período de tiempo. Una vez más, una simulación por eventos salta de un evento a otro, mientras que una vez accionado el producto de simulación en un paso de tiempo constante.

Me parece que el ejercicio le está pidiendo que implementar un planificador multitarea cooperativa. El programador funciona en tiempo virtual (tiempo de garrapatas que definir / implementar en cualquier nivel que desee), elige una tarea a ejecutar sobre la base de la cola (tenga en cuenta que la descripción se menciona que había necesidad de implementar uno), y cuando la tarea actual es hecho, el planificador selecciona la siguiente y comienza funcionando.

La estructura generalizada de una simulación de eventos discretos se basa en una cola de prioridad enchavetada en un valor de tiempo. A un nivel amplio que va así:

    While (not end condition):
        Pop next event (one with the lowest time) from the priority queue
        Process that event, which may generate more events
        If a new event is generated:
            Place this on the priority queue keyed at its generated time

Los co-rutinas cambian la vista del modelo de ser evento centrado en a ser entidad-céntrica. Las entidades pueden pasar por algún ciclo de vida (por ejemplo, aceptar trabajo, apropiación de recursos X, trabajo procesos, recursos liberación X, trabajo lugar en cola para el paso siguiente). Esto es algo más fácil de programar como los recursos de agarre se manejan con las primitivas de sincronización de semáforos parecidos. Los trabajos y las primitivas de sincronización generan los eventos y ponerlos en cola detrás de las escenas.

Esto proporciona un modelo conceptualmente similar a los procesos en un sistema operativo y un programador de despertar el proceso hasta cuando su entrada o un recurso compartido que ha solicitado está disponible. El modelo de co-rutina hace que la simulación mucho más fácil de entender, que es útil para la simulación de sistemas complejos.

(No soy un C ++ dev)

Probablemente, lo que significa es que se necesita para crear una clase de tareas (como en eventos) que consistirá en su mayoría de un puntero de función de devolución de llamada y una hora programada, y se pueden almacenar en una lista en la clase de programador, que a su vez básicamente debe llevar un registro de un contador de tiempo y llamar a la función de cada tarea cuando llegue el momento. Estas tareas deben ser creados por los objetos de la simulación.

Si necesita ayuda en el lado de la simulación discreta, seguir adelante y editar la pregunta.

Esto es en respuesta al comentario de titaniumdecoy a la respuesta de SottieT812. Su demasiado grande para un comentario, así que decidí hacerlo otra respuesta.

Es por eventos en el sentido de que el estado de simulación sólo los cambios en respuesta a un evento. Por ejemplo, suponga que tiene dos eventos lanzamiento del misil y impacto de misiles . Cuando el lanzamiento se ejecuta caso, se da cuenta de cuándo y dónde va a impactar, y los horarios de un impacto evento durante el tiempo apropiado. La posición del misil no está calculada entre el lanzamiento y el impacto, aunque probablemente tendrá un método que puede ser llamado por otros objetos para conseguir la posición en un momento determinado.

Esto es en contraste a una simulación en tiempo conducido, donde se calcula la posición exacta del misil (y cualquier otro objeto en la simulación) después de cada paso de tiempo, por ejemplo 1 segundo.

Dependiendo de las características del modelo, la fidelidad de la respuesta se requiere, y muchos otros factores, ya sea por eventos o simulación en tiempo impulsado puede funcionar mejor.

Editar: Si alguien está interesado en aprender más, echa un vistazo a los papeles de la href="http://wintersim.org/" rel="nofollow noreferrer"> Simulation Conference invierno

Hay un libro y un marco llamado POBLACIÓN (Modelado de eventos discretos en Simula) que describe un marco basado en rutinas conjuntas (el DEMOS del mismo nombre).A pesar de tener aproximadamente 30 años, DEMOS es en realidad un sistema bastante bueno, y Graham Birtwistle es un tipo realmente agradable.

Si implementa co-rutinas en C++ (piense en setjump/longjump), debería consultar este libro para obtener una descripción de una realmente muy elegante marco de modelado de eventos discretos.Aunque tiene 30 años, es un clásico atemporal y todavía tiene una base de seguidores.

En el documento vinculado a por "me.yahoo.com / ...", que describe la clase task.h:

  1. Las tareas se ejecutan en paralelo
  2. Una tarea puede ser suspendido y se reanuda después

La biblioteca se describe como un método de multiprogramación.

¿Es posible hacer esto sin usar hilos o procesos separados?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top