Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Работа со временными отрезками в си
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Buratino
Какие способы существуют для задания определённых промежутков времени с помощью си?
andrewlekar
http://www.cplusplus.com/reference/ctime/

Но вообще вопрос непростой. Функции для работы с временем обычно достаточно сильно завязаны на используемую ось. Если это линукс, то там есть clock_gettime и usleep. Если это windows, то QueryPerformanceFrequency и Sleep. Если оси нет вообще, то можно использовать просто временные задержки или портировать функции из time.h - для этого нужно написать свою реализацию функций __time32 и/или __time64.
Buratino
Цитата
Но вообще вопрос непростой. Функции для работы с временем обычно достаточно сильно завязаны на используемую ось. Если это линукс, то там есть clock_gettime и usleep. Если это windows, то QueryPerformanceFrequency и Sleep. Если оси нет вообще, то можно использовать просто временные задержки или портировать функции из time.h - для этого нужно написать свою реализацию функций __time32 и/или __time64.


Использую Win32 Console, Sleep() как таковой не подходит по причине того, что нужно постоянно использовать поток, а вот QueryPerformanceFrequency - это интересно
andrewlekar
Вот реализация posix совместимого gettime.c для винды. Не знаю, правда, как у этого кода с совместимостью со старыми виндами...

CODE
#include "gettime.h"

#ifdef __cplusplus
extern "C" {
#endif

static LARGE_INTEGER getFILETIMEoffset()
{
SYSTEMTIME s;
FILETIME f;
LARGE_INTEGER t;

s.wYear = 1970;
s.wMonth = 1;
s.wDay = 1;
s.wHour = 0;
s.wMinute = 0;
s.wSecond = 0;
s.wMilliseconds = 0;
SystemTimeToFileTime(&s, &f);
t.QuadPart = f.dwHighDateTime;
t.QuadPart <<= 32;
t.QuadPart |= f.dwLowDateTime;
return (t);
}

int clock_gettime(clockid_t clk_id, struct timespec *tp)
{
LARGE_INTEGER t;
FILETIME f;
double microseconds;
static LARGE_INTEGER offset;
static double frequencyToMicroseconds;
static int initialized = 0;
static BOOL usePerformanceCounter = 0;

(void)clk_id;

if (!initialized) {
LARGE_INTEGER performanceFrequency;
initialized = 1;
usePerformanceCounter = QueryPerformanceFrequency(&performanceFrequency);
if (usePerformanceCounter) {
QueryPerformanceCounter(&offset);
frequencyToMicroseconds = (double)performanceFrequency.QuadPart / 1000000.;
} else {
offset = getFILETIMEoffset();
frequencyToMicroseconds = 10.;
}
}
if (usePerformanceCounter) QueryPerformanceCounter(&t);
else {
GetSystemTimeAsFileTime(&f);
t.QuadPart = f.dwHighDateTime;
t.QuadPart <<= 32;
t.QuadPart |= f.dwLowDateTime;
}

t.QuadPart -= offset.QuadPart;
microseconds = (double)t.QuadPart / frequencyToMicroseconds;
t.QuadPart = (LONGLONG)microseconds;
tp->tv_sec = (long)(t.QuadPart / 1000000);
tp->tv_nsec = (t.QuadPart % 1000000) * 1000;
return (0);
}

#ifdef __cplusplus
}
#endif
Buratino
Цитата(andrewlekar @ Sep 5 2013, 10:51) *
Вот реализация posix совместимого gettime.c для винды. Не знаю, правда, как у этого кода с совместимостью со старыми виндами...

CODE
#include "gettime.h"

#ifdef __cplusplus
extern "C" {
#endif

static LARGE_INTEGER getFILETIMEoffset()
{
SYSTEMTIME s;
FILETIME f;
LARGE_INTEGER t;

s.wYear = 1970;
s.wMonth = 1;
s.wDay = 1;
s.wHour = 0;
s.wMinute = 0;
s.wSecond = 0;
s.wMilliseconds = 0;
SystemTimeToFileTime(&s, &f);
t.QuadPart = f.dwHighDateTime;
t.QuadPart <<= 32;
t.QuadPart |= f.dwLowDateTime;
return (t);
}

int clock_gettime(clockid_t clk_id, struct timespec *tp)
{
LARGE_INTEGER t;
FILETIME f;
double microseconds;
static LARGE_INTEGER offset;
static double frequencyToMicroseconds;
static int initialized = 0;
static BOOL usePerformanceCounter = 0;

(void)clk_id;

if (!initialized) {
LARGE_INTEGER performanceFrequency;
initialized = 1;
usePerformanceCounter = QueryPerformanceFrequency(&performanceFrequency);
if (usePerformanceCounter) {
QueryPerformanceCounter(&offset);
frequencyToMicroseconds = (double)performanceFrequency.QuadPart / 1000000.;
} else {
offset = getFILETIMEoffset();
frequencyToMicroseconds = 10.;
}
}
if (usePerformanceCounter) QueryPerformanceCounter(&t);
else {
GetSystemTimeAsFileTime(&f);
t.QuadPart = f.dwHighDateTime;
t.QuadPart <<= 32;
t.QuadPart |= f.dwLowDateTime;
}

t.QuadPart -= offset.QuadPart;
microseconds = (double)t.QuadPart / frequencyToMicroseconds;
t.QuadPart = (LONGLONG)microseconds;
tp->tv_sec = (long)(t.QuadPart / 1000000);
tp->tv_nsec = (t.QuadPart % 1000000) * 1000;
return (0);
}

#ifdef __cplusplus
}
#endif


Кодище!!
Вы скинули хорошую ссылку, нашёл вроде то, что нужно, по крайней мере что-то получилось слепить на первых порах, буду смотреть дальше
lbm
Цитата(Buratino @ Sep 5 2013, 10:26) *
Какие способы существуют для задания определённых промежутков времени с помощью си?


Попробуйте посмотреть в MSDN раздел
Waitable Timer Objects

Функции:
CreateWaitableTimer
SetWaitableTimer
...

Эти средства позволяют отмерять промежутки времени с точностью до ms
XVR
Цитата(lbm @ Sep 20 2013, 12:54) *
Эти средства позволяют отмерять промежутки времени с точностью до ms
Уточнение - позволяют задавать промежутки времени с точностью до 1 ms. А вот отрабатывать они их будут с той точностью, какая получится. В общем случае не лучше точности системных часов (десятки ms)
Однако, часами можно управлять - см тут
Buratino
Решил вопрос с помощью компонента Timer в С++ Builder, самый простейший вариант, точность порядка десятков мс, но она хромает, причём нормально sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.