Вопрос по system-calls, sleep, milliseconds, c – Спите в течение миллисекунд в Windows, Linux, Solaris, HP-UX, IBM AIX, Vxworks, Wind River Linux?

10

Я должен написать программу на C, которая должна спать в течение миллисекунд, которая должна работать на различных платформах, таких как Windows, Linux, Solaris, HP-UX, IBM AIX, Vxworks и Windriver Linux.

НаWindows,Sleep Системный вызов будет работать только за миллисекунды.НаLinux,sleep будет работать на секундах;usleep будет выполнять на микросекундах, и это 'Доступно также на Solaris.ВVxWorksЯ надеюсь, что смогу реализовать с помощьюtaskDelay а также .sysClkRateSet

Как мне добиться этого миллисекундного сна в HP-UX, IBM AIX и Wind River Linux?

Следующая ссылка отвечает на ваш вопрос?stackoverflow.com/questions/1157209/... kunal18
Возможный дубликатЕсть ли альтернативная функция сна в C до миллисекунд? Jonathan Leffler
usleep является POSIX, поэтому должен быть во всех POSIX-совместимых системах (таких как HP / UX, AIX и т. д.). Это'помечены как устаревшие, хотя, в пользуnanosleep который с другой стороны помечен как необязательный. Some programmer dude
Обратите внимание, что только потому, что вы можете найти способэкспресс задержка n миллисекунд,Абсолютно нет гарантии, что операционная система хоста будетдать Вы именно то, что вы просите. ОС: список, который вы перечисляете, обычно не в реальном времени, поэтому они, скорее всего, не гарантируют такие вещи; Когда ваша задержка заканчивается, ЦП может занять более высокоприоритетную задачу. unwind

Ваш Ответ

3   ответа
2

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

Эта функция повтора сочетает в себе преимущества сна и usleep, чтобы вы могли ввести int или float для желаемой задержки, и 0.1 будет спать 10 секунд, а 3 будет спать 3 секунды. 3,5 секунды рассматриваются как 3 секунды.

Протестировано на Linux Mint 18.3 (Ubuntu 16.04.9) как C и C ++ с gcc 5.4.0.

#include <unistd.h>

void snooze(double t) {(t > 1.0) ? sleep(t) : usleep(t*1000000);}

snooze(0.01);  // call function to sleep for 10ms
</unistd.h>



Для полноты, это версия для сна. Это'потенциально более точный, чем версия usleep и неt угроза устаревания.

#include <time.h>
#include <math.h>

void snooze(double t) {
    struct timespec req = {t, fmod(t, 1.0) * 1E9};
    nanosleep(&req, NULL);
}

// struct timespec req = {t, fmod(t, 1.0) * 1E9};
//  is equivalent to:
// struct timespec req = {0};
// req.tv_sec = t;
// req.tv_nsec = fmod(t, 1.0) * 1000000000L;

// NULL as value for *rem so no resumption after signal interrupts

snooze(1.99);  // call for delay of 1.99 seconds
</math.h></time.h>

По предложению@alk, следующие версии возвращают вызванную функцию сна 's ошибка должна произойти или 0 в случае успеха Определение структуры rem (aining) также разрешает возобновление после прерывания сигнала.

int snooze(double t) {
    return (t > 1.0) ? sleep(t) : usleep(t*1000000);
}

int snooze(double t) {
    struct timespec req = {t, fmod(t, 1.0) * 1E9};
    struct timespec rem = {0, 0.0};
    return nanosleep(&req, &rem);
}
Для полной полноты вы можете позаботиться о значении, возвращаемом используемыми функциями. alk
Спасибо за предложениеалк, Я'мы добавили варианты. John 9631
16

Вероятно, обертка, использующая платформу#defines сделает:

#if defined(WIN32)
  #include <windows.h>
#elif defined(__UNIX__)
  #include <unistd.h>
#else
#endif

...

int millisleep(unsigned ms)
{
#if defined(WIN32)
  SetLastError(0);
  Sleep(ms);
  return GetLastError() ?-1 :0;
#elif defined(LINUX)
  return usleep(1000 * ms);
#else
#error ("no milli sleep available for platform")
  return -1;
#endif
}
</unistd.h></windows.h>

Обновить

Ссылаясь наДжонатан'комментарий нижепожалуйста, найдите более современную, более портативную (и исправленную) версию здесь:

#if defined(WIN32)
  #include <windows.h>
#elif defined(__unix__)
  #include <time.h>
  #include <unistd.h>
#else
#endif

...

int millisleep(unsigned ms)
{
#if defined(WIN32)

  SetLastError(0);
  Sleep(ms);
  return GetLastError() ?-1 :0;

#elif _POSIX_C_SOURCE >= 199309L

  /* prefer to use nanosleep() */

  const struct timespec ts = {
    ms / 1000, /* seconds */
    (ms % 1000) * 1000 * 1000 /* nano seconds */
  };

  return nanosleep(&ts, NULL);

#elif _BSD_SOURCE || \
  (_XOPEN_SOURCE >= 500 || \
     _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) && \
  !(_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700)

  /* else fallback to obsolte usleep() */

  return usleep(1000 * ms);

#else

# error ("No millisecond sleep available for this platform!")
  return -1;

#endif
}
</unistd.h></time.h></windows.h>
@JonathanLeffler: Спасибо за уведомление. Исправленный. alk
В соответствии с POSIX 2004 годаusleep() звонок был отмеченустаревшее»и был удален из POSIX 2008. Предпочтительная альтернативаnanosleep(), Общая тенденция в POSIX - отдавать предпочтениеstruct timespec, который имеет наносекундное разрешение, по сравнению с такими альтернативами, какstruct timeval который имеет только микросекундное разрешение, илиusleep() который нене использовать структуру, но работает и с микросекундным разрешением. Jonathan Leffler
это действительно очень хороший ответ Алк Grijesh Chauhan
2

select с пустыми наборами FD и тайм-аутом, который вы хотите. От :man select

Некоторые вызовы кода select () со всеми тремя наборами пустыми, с нулевым nfds и таймаутом, отличным от NULL, в качестве довольно переносимого способа спать с точностью до секунды.

На самом деле это может быть лучшим решением для любой системы, отличной от Windows.

Спасибо за ваш ответ. в настоящее время мы используем это только в некоторых платформахselect не доступен. Как Windriver Linuxselect не доступен. rashok

Похожие вопросы