Я - встроенный программист, пытающийся моделировать вытесняющий планировщик в реальном времени в среде Win32, используя Visual Studio 2010 и MingW (как две отдельные среды сборки).Я очень зеленый в среде планирования Win32 и столкнулся с кирпичной стеной с тем, что я пытаюсь сделать.Я не пытаюсь добиться поведения в реальном времени - просто заставить симулированные задачи работать в том же порядке и последовательности, что и на реальном целевом оборудовании.
Имитируемый планировщик реального времени имеет простую цель -всегда выполняйте задачу с наивысшим приоритетом (поток), которая может выполняться.Как только задача становится способной выполняться - она должна выгрузить текущую задачу, если у нее приоритет выше текущей задачи.Задача может стать способной выполняться из-за внешнего события, которого она ждала, или истечения времени ожидания / времени блокировки / истечения времени ожидания - с прерыванием по тику, генерирующим временную базу.
В дополнение к этому упреждающему поведению, задача может дать или добровольно отказаться от своего временного интервала, потому что она выполняет функцию типа сна или ожидания.
Я имитирую это, создавая поток Win32 с низким приоритетом для каждой задачи, которая создается реальноймоделируемый планировщик времени (поток фактически выполняет переключение контекста, которое планировщик выполняет для реальной встроенной цели), поток Win32 со средним приоритетом в качестве обработчика псевдо-прерываний (обрабатывает смоделированные тиковые прерывания и выдает запросы, которые ему сообщаются с использованием события Win32объект) и поток Win32 с более высоким приоритетом для имитации периферийного устройства, генерирующего тиковые прерывания.
Когда обработчик псевдо-прерываний устанавливает, что должно произойти переключение задач, он приостанавливает текущий выполняющийся поток с использованием SuspendThread () и возобновляет поток, который выполняет вновь выбранную задачу, используя ResumeThread ().Из множества задач и связанных с ними потоков Win32, которые могут быть созданы, только один поток, который управляет задачей, когда-либо будет находиться в состоянии ожидания в любой момент времени.
Важно, чтобы приостановленный поток немедленно приостанавливал вызов SuspendThread () и чтобы поток обработки псевдо-прерываний выполнялся, как только событие, сообщающее ему, что прерывание находится в состоянии ожидания, сигнализируется - но это неПоведение, которое я наблюдаю.
В качестве примера проблемы, для которой у меня уже есть обходной путь: Когда задача / поток дает результат, событие yield фиксируется в переменной, а поток обработки прерываний сигнализируется, поскольку существует псевдопрерывание (выход), который нуждается в обработке.Теперь в системе реального времени, поскольку я привык к программированию, я ожидал бы, что поток обработки прерываний немедленно выполнит то, о чем он сигнализирует, потому что он имеет более высокий приоритет, чем поток, который его сигнализирует.В среде Win32 я вижу, что поток, сигнализирующий о потоке с более высоким приоритетом, продолжает работать некоторое время, прежде чем будет приостановлен - либо потому, что требуется некоторое время, прежде чем сигнальный поток с более высоким приоритетом начинает выполняться, либо потому, что требуется некоторое время для приостановкизадача на самом деле перестать работать - я не уверен, какой.В любом случае это может быть легко исправлено путем создания сигнального блока потока Win32 на семафоре после сигнализации потока обработки прерываний Win32, и заставить поток обработки прерываний Win32 разблокировать поток, когда он завершит свою функцию (рукопожатие).Эффективно используя синхронизацию потоков, чтобы заставить шаблон планирования к тому, что мне нужно.Для этой цели я использую SignalObjectAndWait ().
При использовании этого метода моделирование работает идеально, когда моделируемый планировщик реального времени работает в кооперативном режиме, но не (как требуется) в вытесняющем режиме.
Проблема с преимущественным переключением задач состоит в том, что, я думаю, то же самое, задача продолжает выполняться в течение некоторого времени после того, как ей было приказано приостановить работу, прежде чем она фактически перестает работать, поэтому нельзя гарантировать, что система будет оставаться в согласованном состоянии, когда поток, который запускает задачу, приостанавливается. Однако в упреждающем случае, поскольку задача не знает, когда это произойдет, нельзя использовать тот же метод использования семафора, чтобы предотвратить продолжение игры Win32 до ее следующего возобновления.
Кто-нибудь сделал это так далеко внизу этого поста - извините за его длину!
Мои вопросы:
Как я могу заставить планирование Win32 (XP) запускать и останавливать задачи немедленно при вызове функций потоков приостановки и возобновления - или - как я могу заставить поток Win32 с более высоким приоритетом немедленно начать выполнение, чтобы он мог сделать это (объект, на котором он заблокирован, сигнализируется). Эффективно заставляет Win32 перепланировать запущенные процессы.
Существует ли способ асинхронной остановки задачи для ожидания события, когда его нет в пути последовательного выполнения задачи / потоков.
Симулятор хорошо работает в среде Linux, где сигналы POSIX используются для эффективного прерывания потоков - есть ли эквивалент в Win32?
Спасибо всем, кто нашел время для прочтения этого длинного поста, и особенно спасибо всем, кто сможет протянуть руку «инженеров реального времени» через этот лабиринт Win32.