2016-06-16 1 views
0

У меня есть поток, который в конечном итоге получит данные от датчика каждые 1 мс и выполнит некоторую обработку, которая должна занимать менее 1 мс (скажем, 0,5 мс). На данный момент я хочу смоделировать датчик, используя другой поток. Поэтому моя цель - создать поток, который генерирует данные каждые 1 мс и отправляет их в другой поток. Предположим, что время генерации и отправки незначительно.Выполнение кода каждые 1 миллисекунда

Я пробовал использовать this_thread::sleep_for, но это не сработало. У меня в основном случайное время сна где-то между 1 мс и 15 мс. Я думаю, что могу использовать chrono::high_resolution_clock. Но для этого потребуется ожидание.

Любые другие идеи?

Я могу рассчитывать в среднем на 1 мс при условии, что он ни в коем случае не меньше времени обработки.

+5

На какой платформе вы работаете? Разрешение часов (и программный контроль над ним) варьируется между Windows, Linux и т. Д. Это означает, что разрешение 1 мс обычно не может быть надежно обеспечено за пределами операционных систем реального времени. – nephtes

+0

Что сказал @nephtes. Вероятно, вы застряли в оживленном ожидании. – user4581301

+0

Ни в коем случае вы не получите 1 мс сна в системе, отличной от реального времени. – SergeyA

ответ

1

Если вы не возражаете тратить вычислительные мощности, использовать активное ожидание: спина до миллисекунды истечет:

auto start = std::chrono::high_resolution_clock::now(); 
auto now = start; 
while (not_ready(start, now)) 
{ 
    now = std::chrono::high_resolution_clock::now(); 
} 
+0

Не будет работать в системах, где получение количества тиков - это системный вызов. – SergeyA

+0

Замечание о старой версии VS на Windows, high_resolution_clock было не очень, erm, с высоким разрешением, поэтому вам нужно будет использовать QueryPerformanceCounter или getSystemTimeAsFiletimePrecise. Это исправлено iirc в последней версии VS. –

0

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

0

Я рекомендую установить таймер для перезагрузки 1 миллисекунды и использовать вектор прерывания для таймера.

На встроенной системе, над которой я работаю, у нас есть таймер таймера 1 мс ISR. Мы настроили аппаратное обеспечение, чтобы сделать его максимально точным (включая использование осциллографов для измерения).

Возможно, вы захотите сделать это приоритетным прерыванием или задачей.

Используемый нами процессор поставляется с несколькими таймерами. Когда таймер истекает, он может выполнять код как прерывание.

+0

Не требовалось ли разрешение Ring0? – SergeyA

+0

Разрешение полностью зависит от платформы. Используемая платформа использует Micrium COS-II. Нет колец. Просто память процессора ARM и другие устройства. Мы не требуем разрешения на выполнение; сохраняя вещи просто. –

+0

Хорошо :) интересно сейчас. Я так далеко от встроенных :) – SergeyA

0

В Windows вы можете запросить настраиваемое разрешение таймера с помощью вызова timeBeginPeriod() (см. this example). Вероятно, вы все же захотите проверить, насколько близко он на самом деле доходит до 1 мс.

Также имейте в виду, что даже занятый-ожидание здесь не является верным решением. Если процессор находится на достаточной нагрузке, нет никакой гарантии, что ваша программа получит время выполнения в течение заданного 1-миллисекундного фрагмента.

0

Вы хотите просто спать с интервалом менее 1 мс? Вы пробовали usleep() (unistd.h) или nanosleep() (time.h)? Может возникнуть некоторый джиттер из-за расписания неточностей - если это неприемлемо, вам нужно прибегнуть к цину вращения.

+0

Из того, что я сейчас понимаю, планировщик не может работать в такой короткий промежуток времени. Разве это не так? – ThP

+0

Я не понимаю, почему нет, если машина не загружена или вам нужно очень точное время. Если вам нужно очень точное время, вы можете только вращаться; уступка процессора ставит вас во благо планировщика. Но это звучит не так, как будто у вас действительно есть такое строгое требование. Если usleep()/microsleep() никогда не могли предложить примерно то, что они рекламируют из-за планировщика, я не думаю, что они были бы столь же распространены, как и они. – gaugeinvariance