Soy un programador incrustado que intenta simular un planificador preventivo en tiempo real en un entorno Win32 utilizando Visual Studio 2010 y MingW (como dos entornos de compilación separados). Estoy muy verde en el entorno de programación de Win32 y he golpeado una pared de ladrillo con lo que estoy tratando de hacer. No estoy tratando de lograr un comportamiento en tiempo real, solo para que las tareas simuladas se ejecuten en el mismo orden y secuencia que lo harían en el hardware objetivo real.Forzar la programación de hilos de Win32 a una secuencia definida según la prioridad
El programador en tiempo real que se simula tiene un objetivo simple: siempre ejecute la tarea de mayor prioridad (subproceso) que se puede ejecutar. Tan pronto una tarea puede ejecutarse, debe adelantarse a la tarea que se está ejecutando actualmente si tiene una prioridad más alta que la tarea que se está ejecutando. Una tarea puede volverse capaz de ejecutarse debido a un evento externo que estaba esperando, o un tiempo de espera/tiempo de bloqueo/tiempo de espera que expira, con una interrupción de marcación que genera la base de tiempo.
Además de este comportamiento preventivo, una tarea puede ceder o ser voluntaria para renunciar a su segmento de tiempo porque está ejecutando una función de tipo espera o espera.
Estoy simulando esto creando un hilo Win32 de baja prioridad para cada tarea creada por el programador en tiempo real simulado (el hilo efectivamente cambia el contexto que el planificador haría en un objetivo incrustado real), una prioridad media Win32 thread como un controlador de pseudointerrupción (maneja interrupciones simuladas de marcación y solicitudes de rendimiento que se le señalan utilizando un objeto de evento Win32), y una secuencia de Win32 de mayor prioridad para simular el periférico que genera las interrupciones de marcación.
Cuando el manejador de pseudointerrupción establece que debe producirse un cambio de tarea, suspende el subproceso que se está ejecutando utilizando SuspendThread() y reanuda el subproceso que ejecuta la tarea recién seleccionada utilizando ResumeThread(). De las muchas tareas y sus subprocesos Win32 asociados que se pueden crear, solo un subproceso que administre la tarea estará fuera del estado suspendido en cualquier momento.
Es importante que un hilo suspendido suspenda inmediatamente que se invoca SuspendThread(), y que el hilo de manejo de pseudointerrumpida se ejecute tan pronto como se señalice el evento que indica que una interrupción está pendiente, pero este no es el comportamiento I estoy viendo. Como un problema de ejemplo que ya tengo para: Cuando una tarea/hilo produce el evento de rendimiento se enclava en una variable y el hilo de manejo de interrupción se señala como hay una pseudointerrupción (el rendimiento) que necesita tratamiento. Ahora, en un sistema de tiempo real, como estoy acostumbrado a programar, esperaría que el hilo de manejo de interrupciones se ejecute inmediatamente que se señaliza porque tiene una prioridad más alta que el hilo que lo señala. Lo que veo en el entorno de Win32 es que el hilo que señala el hilo de mayor prioridad continúa durante algún tiempo antes de suspenderse, ya sea porque toma algún tiempo antes de que el hilo de mayor prioridad señalizado comience a ejecutarse o porque lleva algo de tiempo suspenderlo tarea para realmente dejar de funcionar, no estoy seguro de cuál. En cualquier caso, esto puede ser correcto haciendo el bloque de hilos Win32 con señal en un semáforo después de señalar el hilo de manejo de interrupción Win32, y hacer que la interrupción que maneja el hilo Win32 desbloquee el hilo cuando haya terminado su función (handshake). Usar de manera efectiva la sincronización de hilos para forzar el patrón de programación a lo que necesito. Estoy usando SignalObjectAndWait() para este propósito.
Usando esta técnica, la simulación funciona perfectamente cuando el programador en tiempo real que se está simulando está funcionando en modo cooperativo, pero no (como se necesita) en modo preventivo. El problema con la conmutación de tareas preventivas es que supongo que la tarea continúa ejecutándose durante un tiempo después de que se le haya indicado que suspenda antes de que realmente se ejecute, por lo que no se puede garantizar que el sistema se mantenga en estado constante. el hilo que ejecuta la tarea se suspende. Sin embargo, en el caso de preferencia, dado que la tarea no sabe cuándo va a suceder, no se puede utilizar la misma técnica de usar un semáforo para evitar que el ataque de Win32 continúe hasta que se reanude.
¿Alguien ha llegado hasta aquí en este post? ¡Disculpe por su longitud!
Mis preguntas son entonces:
¿Cómo puedo forzar Win32 programación (XP) para iniciar y detener tareas de inmediato que las funciones de suspensión y reanudación de rosca se llaman - o - ¿Cómo puedo forzar una mayor prioridad Win32 hilo para comenzar a ejecutar inmediatamente que es capaz de hacerlo (el objeto que está bloqueado se señaliza). Forzar efectivamente a Win32 a reprogramar sus procesos en ejecución.
Hay alguna forma de detener asincrónicamente una tarea para esperar un evento cuando no está en la ruta de ejecución secuencial tarea/hilos.
El simulador funciona bien en un entorno Linux donde las señales POSIX se utilizan para interrumpir efectivamente los hilos. ¿Hay un equivalente en Win32?
Gracias a cualquiera que haya tomado el tiempo de leer este post largo, y sobre todo gracias por adelantado a las personas que puedan sostener la mano de mi 'ingenieros' en tiempo real a través de este laberinto de Win32.
Pero las fibras no se ejecutarán simultáneamente en varios núcleos. –
Gracias por la sugerencia.Buscaré algún material de referencia sobre las fibras mañana. – Richard
@ Zan: múltiples fibras se pueden ejecutar en un solo subproceso, y puede ejecutar varios subprocesos, uno para cada núcleo. –