suspendThread в окнах

Коротко говоря, я пишу симулятор для ОСРВ. Как обычно, основная проблема заключается в симуляции переключения контекста. В случае прерываний становится действительно трудно не отклоняться от "хороших" правил кодирования.

Скажем, задача А запущена, а пользовательское приложение рассчитывает свои безобидные личные вещи, которые будут работать долго. во время этой задачи A должно произойти прерывание X. (подсказка: задача A не имеет никакого отношения к запуску этого прерывания X)... теперь, как мне выполнить переключение контекста с Задачи A на обработчик прерываний X?

Моя текущая реализация основана на потоке контекста, который ожидает, пока не будет запрошено переключение контекста; поток контроллера прерываний, который может генерировать прерывания, если кто-то запрашивает запуск прерывания; и основной поток, который выполняет задачу А. Теперь я использую поток контроллера прерываний для генерации нового потока для прерывания X, а затем запрашиваю поток контекста для переключения контекста. Контекстный поток Приостанавливает задачу Основной поток и возобновляет поток обработчика прерываний X. В конце потока обработчика прерываний X основной поток задачи A возобновляется.

[Править] просто чтобы уточнить, я уже знаю, приостановка и прекращение потоков извне действительно плохо. Вот почему я задал этот вопрос. Плюс, пожалуйста, не рекомендуйте использовать событие и т. Д. Для управления Задачей А. Это код приложения пользователя, и я не могу его контролировать. Он может даже использовать while(1){}, если хочет...

1 ответ

Решение

Я подозреваю, что вы не можете делать то, что хотите, таким образом.

Вы упомянули, что приостановка потока извне - это действительно плохо. Причина в том, что вы понятия не имеете, что делает поток, когда приостанавливаете его. Невозможно узнать, владеет ли поток в настоящее время мьютексом; если это произойдет, любой другой поток, пытающийся получить доступ к тому же мьютексу, будет заблокирован.

У вас проблема в том, что время выполнения, используемое потоками, которые могут быть приостановлены, совпадает с тем, которое используется супервизором. Это означает, что существует много потенциальных таких тупиков между супервизором и другими потоками.

В реальной среде (т. Е. Не в симуляторе) ядро ​​операционной системы может приостанавливать потоки, потому что существуют проверки, чтобы гарантировать, что эти взаимоблокировки не могут возникнуть. Я не знаю деталей, но это, вероятно, включает в себя маскирование прерываний в определенных критических точках и, вероятно, не совместное использование одних и тех же мьютексов между кодом пользовательского режима и критическими частями планировщика ядра. (В вашем случае это означало бы, что ваш планировщик не может использовать те же функции API ОС, прямо или косвенно, которые разрешено использовать пользовательским потокам, если они включают мьютексы. Это, конечно, было бы практически невозможно достижения.)

Причина, по которой я спросил в комментарии, имеете ли вы какой-либо контроль над компилятором пользовательского кода, заключается в том, что если вы управляете компилятором, то вы можете организовать для пользовательского кода эффективную маскировку прерываний в течение каждой инструкции и только в другом потоке. -определенные точки между инструкциями. Вот как это делается в системе управления, над которой я работаю.

Другой аспект - это зависимость от платформы. В Linux и других Unix-подобных операционных системах у вас есть сигналы, похожие на прерывания в пользовательском режиме. Вы могли бы потенциально использовать сигналы для эмуляции переключения контекста, хотя у вас все равно будет та же проблема с мьютексами. Насколько мне известно, в Windows нет абсолютно никакого эквивалента именно из-за уже заявленной проблемы. Ближайшая вещь - это асинхронный вызов процедуры, но он будет выполняться только тогда, когда поток перешел в состояние ожидания с оповещением (что означает, что поток находится в детерминированном состоянии и теперь безопасен для прерывания).

Я думаю, вам придется переосмыслить всю концепцию, чтобы ваш супервизорный поток имел привилегированный контроль над пользовательскими потоками, которые ОС имеет в неэмулируемой среде. Это, вероятно, потребует замены компилятора или библиотек времени выполнения, или обоих, чем-то по вашему собственному усмотрению.

Другие вопросы по тегам