Точно-миллисекундное планирование будущих событий в C ++ / CLI - PullRequest
1 голос
/ 05 июня 2010

Мне нужно создать смешанную сборку C ++ / CLI, которая может планировать будущие вызовы в собственную DLL с точностью до миллисекунды.

Это, конечно, будет означать установку таймера ( какого типа? ) на миллисекунду или три заранее, затем вращение до момента и вызов собственной функции DLL.

Исходя из того, что я прочитал, я могу предположить, что обратный вызов, который вызывает таймер, должен быть собственным, чтобы убедиться, что нет thunk или GC, чтобы задержать обработку обратного вызова таймера.

Должен ли весь поток или процесс быть нативным и без CLR, или же это может быть сделано с такой же точностью, если неуправляемый #pragma или задать один файл сборки для компиляции как нативный?

Если так, то как?

Если действительно нет способа сделать это в смешанном режиме C ++ / CLI, какой самый простой способ настроить приложение / нить (т. Е. DLL или exe?) Для его обработки и получения данных обратно и далее между нативными и управляемыми потоками / приложениями?

Ответы [ 2 ]

3 голосов
/ 05 июня 2010

Вам нужен весь поток, чтобы быть без CLR. Как только любой управляемый код выполняется в потоке, он будет добавлен в список потоков CLR для приостановки во время сбора.

Ваш последний вопрос, тем не менее, предполагает, что вы не имеете ни малейшего представления о многопоточности. Нет соответствия между потоками и библиотеками DLL. DLL может иметь много потоков, и каждый поток может запускать код из многих библиотек DLL (на самом деле, всегда, если считать библиотеки Windows DLL). Вы также не используете фразу «критический раздел» обычным способом.

Сборка C ++ / CLI в смешанном режиме может содержать собственный поток (запустить его с помощью собственного вызова CreateThread, передать процедуру собственного потока и не вызывать какой-либо управляемый код прямо или косвенно из этого потока). Ваша жизнь станет немного проще, если вы напишите код для собственного потока в одном или нескольких файлах, настроенных для компиляции без / clr, а отсутствие видимого управляемого кода облегчает его избегание, хотя остерегайтесь указателей на функции, которые могут быть обернуты управляемые делегаты.

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

РЕДАКТИРОВАТЬ: указатели функций, которые обертывают управляемые делегаты, создаются путем вызова Marshal :: GetDelegateForFunctionPointer . После этого они действуют как указатели на собственные функции (их можно отличить друг от друга), и использование оператора вызова функции для такого указателя приведет к выполнению управляемого кода в чувствительном потоке. В большинстве случаев это не будет проблемой, просто убедитесь, что вы используете делегаты в качестве ярлыка для создания обратных вызовов к управляемому коду, что вы делаете это из смешанного потока, а не из того, который вы намереваетесь использовать только для собственного использования.

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

Весь thunking должен произойти в смешанном потоке, и он не задержит чувствительный ко времени собственный поток, если смешанный поток не удерживает блокировку, необходимую для собственного потока. Отсюда мое предложение использовать неблокирующий обмен данными.

0 голосов
/ 05 июня 2010

Это не может быть сделано в Windows вообще - извините. Получите ОС, соответствующую вашим требованиям.

  • Обычные таймеры в окнах имеют точность 10 мс.
  • Даже если вы работаете с высокопроизводительными таймерами, в окнах нет гарантии точности, что вызов будет обработан в течение определенного времени - ваш вызов в 1 мс может прийти с опозданием на 5 мс.

То, что вам нужно / кажется, нужно, это операционная система реального времени.

...