Как сделать поток сна/блок для наносекунд (или, по крайней мере, миллисекунд)?
Как я могу заблокировать поток (возможно, процесс) для наносекунд или, возможно, за миллисекунд (по крайней мере)?
Обратите внимание, что я не могу использовать сон, потому что аргумент для сна всегда находится в секундах.
Ответы
Ответ 1
nanosleep
или clock_nanosleep
- это функция, которую вы должны использовать (последняя позволяет вам указывать абсолютное время, а не относительное время, и использовать монотонные часы или другие часы, а не только часы реального времени, которые могут работать в обратном направлении если оператор сбрасывает его).
Помните, однако, что вы редко получаете лучше, чем несколько микросекунд с точки зрения разрешения, и оно всегда округляет продолжительность сна, а не округляет. (Округление вообще было бы невозможно в любом случае, так как на большинстве машин ввод и выход из ядерного пространства занимает больше, чем микросекунда.)
Кроме того, если возможно, я бы предложил использовать вызов, который блокирует ожидание события, а не спящий для крошечных интервалов, а затем опрос. Например, pthread_cond_wait
, pthread_cond_timedwait
, sem_wait
, sem_timedwait
, select
, read
и т.д. В зависимости от того, какую задачу выполняет ваш поток, и как он синхронизируется с другими потоками и/или связывается с внешний мир.
Ответ 2
Один относительно переносимый способ - использовать select()
или pselect()
без файловых дескрипторов:
void sleep(unsigned long nsec) {
struct timespec delay = { nsec / 1000000000, nsec % 1000000000 };
pselect(0, NULL, NULL, NULL, &delay, NULL);
}
Ответ 3
Попробуйте usleep(). Да, это не даст вам наносекундной точности, но микросекунды будут работать = > миллисекунды тоже.
Ответ 4
Точная нано-секундная резолюция будет невозможна на общей ОС Linux из-за того, что в целом дистрибутивы Linux не являются (жесткими) операционными системами реального времени. Если вам действительно нужен оштрафованный контроль времени, подумайте об использовании такой операционной системы.
В Википедии есть список операционных систем реального времени: http://en.wikipedia.org/wiki/RTOS (обратите внимание, что он не говорит, что они мягкие или жесткое реальное время, поэтому вам придется провести некоторое исследование).
Ответ 5
Используя любой вариант сна для pthreads, поведение не гарантируется. Все потоки также могут спать, поскольку ядро не знает о разных потоках. Следовательно, требуется решение, которое может обрабатывать библиотека pthread, а не ядро.
Более безопасным и чистым решением является pthread_cond_timedwait...
pthread_mutex_t fakeMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t fakeCond = PTHREAD_COND_INITIALIZER;
void mywait(int timeInSec)
{
struct timespec timeToWait;
struct timeval now;
int rt;
gettimeofday(&now,NULL);
timeToWait.tv_sec = now.tv_sec + timeInSec;
timeToWait.tv_nsec = now.tv_usec*1000;
pthread_mutex_lock(&fakeMutex);
rt = pthread_cond_timedwait(&fakeCond, &fakeMutex, &timeToWait);
pthread_mutex_unlock(&fakeMutex);
printf("\nDone\n");
}
void* fun(void* arg)
{
printf("\nIn thread\n");
mywait(5);
}
int main()
{
pthread_t thread;
void *ret;
pthread_create(&thread, NULL, fun, NULL);
pthread_join(thread,&ret);
}
Для pthread_cond_timedwait вам нужно указать, сколько времени ждать от текущего времени.
Теперь, используя функцию mywait(), только вызывающий ее поток будет спать, а не другие pthreads.
Ответ 6
nanosleep
позволяет указать точность спящего режима до наносекунд. Однако фактическое разрешение вашего сна, вероятно, будет намного больше из-за ограничений ядра/процессора.
Ответ 7
Во встроенной системе с доступом к нескольким аппаратным таймерам создайте высокоскоростные часы для ваших наносекунд или микросекунд. Создайте макрос, чтобы включить и отключить его, и обрабатывать обработку с высоким разрешением в процедуре обслуживания прерывания таймера.
Если тратящая сила и ожидание не являются проблемой, выполните некоторые инструкции no-op, но убедитесь, что компилятор не оптимизирует ваши ноу-хау. Попробуйте использовать летучие типы.