Как я могу заблокировать поток (возможно, процесс) для наносекунд или, возможно, за миллисекунд (по крайней мере)?
Обратите внимание, что я не могу использовать сон, потому что аргумент для сна всегда находится в секундах.
Как я могу заблокировать поток (возможно, процесс) для наносекунд или, возможно, за миллисекунд (по крайней мере)?
Обратите внимание, что я не могу использовать сон, потому что аргумент для сна всегда находится в секундах.
nanosleep
или clock_nanosleep
- это функция, которую вы должны использовать (последняя позволяет вам указывать абсолютное время, а не относительное время, и использовать монотонные часы или другие часы, а не только часы реального времени, которые могут работать в обратном направлении если оператор сбрасывает его).
Помните, однако, что вы редко получаете лучше, чем несколько микросекунд с точки зрения разрешения, и оно всегда округляет продолжительность сна, а не округляет. (Округление вообще было бы невозможно в любом случае, так как на большинстве машин ввод и выход из ядерного пространства занимает больше, чем микросекунда.)
Кроме того, если возможно, я бы предложил использовать вызов, который блокирует ожидание события, а не спящий для крошечных интервалов, а затем опрос. Например, pthread_cond_wait
, pthread_cond_timedwait
, sem_wait
, sem_timedwait
, select
, read
и т.д. В зависимости от того, какую задачу выполняет ваш поток, и как он синхронизируется с другими потоками и/или связывается с внешний мир.
Один относительно переносимый способ - использовать select()
или pselect()
без файловых дескрипторов:
void sleep(unsigned long nsec) {
struct timespec delay = { nsec / 1000000000, nsec % 1000000000 };
pselect(0, NULL, NULL, NULL, &delay, NULL);
}
Попробуйте usleep(). Да, это не даст вам наносекундной точности, но микросекунды будут работать = > миллисекунды тоже.
Точная нано-секундная резолюция будет невозможна на общей ОС Linux из-за того, что в целом дистрибутивы Linux не являются (жесткими) операционными системами реального времени. Если вам действительно нужен оштрафованный контроль времени, подумайте об использовании такой операционной системы.
В Википедии есть список операционных систем реального времени: http://en.wikipedia.org/wiki/RTOS (обратите внимание, что он не говорит, что они мягкие или жесткое реальное время, поэтому вам придется провести некоторое исследование).
Используя любой вариант сна для 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.
nanosleep
позволяет указать точность спящего режима до наносекунд. Однако фактическое разрешение вашего сна, вероятно, будет намного больше из-за ограничений ядра/процессора.
Во встроенной системе с доступом к нескольким аппаратным таймерам создайте высокоскоростные часы для ваших наносекунд или микросекунд. Создайте макрос, чтобы включить и отключить его, и обрабатывать обработку с высоким разрешением в процедуре обслуживания прерывания таймера.
Если тратящая сила и ожидание не являются проблемой, выполните некоторые инструкции no-op, но убедитесь, что компилятор не оптимизирует ваши ноу-хау. Попробуйте использовать летучие типы.