Как сделать поток сна/блок для наносекунд (или, по крайней мере, миллисекунд)?

Как я могу заблокировать поток (возможно, процесс) для наносекунд или, возможно, за миллисекунд (по крайней мере)?

Обратите внимание, что я не могу использовать сон, потому что аргумент для сна всегда находится в секундах.

Ответ 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, но убедитесь, что компилятор не оптимизирует ваши ноу-хау. Попробуйте использовать летучие типы.