Dec
16
Some C/C++ code targeted for GNU family compilers fail to compile under Windows due to the dependency on sys/time.h
header file. The repository here has provided a neat implementation for it. Basically you need these three files: time.h
, times.h
and times.cpp
. I have included them here (in case the repository ever went dead). Note that this is not my code and the original license of the code was LGPL.
sys/time.h:
#pragma once #ifndef _TIMES_H #include "sys/times.h" #endif
sys/times.h:
#ifndef _TIMES_H #define _TIMES_H #ifdef _WIN32 #include <sys/timeb.h> #include <sys/types.h> #include <winsock2.h> int gettimeofday(struct timeval* t,void* timezone); // from linux's sys/times.h //#include <features.h> #define __need_clock_t #include <time.h> /* Structure describing CPU time used by a process and its children. */ struct tms { clock_t tms_utime; /* User CPU time. */ clock_t tms_stime; /* System CPU time. */ clock_t tms_cutime; /* User CPU time of dead children. */ clock_t tms_cstime; /* System CPU time of dead children. */ }; /* Store the CPU time used by this process and all its dead children (and their dead children) in BUFFER. Return the elapsed real time, or (clock_t) -1 for errors. All times are in CLK_TCKths of a second. */ clock_t times (struct tms *__buffer); typedef long long suseconds_t ; #endif #endif
sys/time.cpp:
#include "sys/times.h" int gettimeofday(struct timeval* t,void* timezone) { struct _timeb timebuffer; _ftime( &timebuffer ); t->tv_sec=timebuffer.time; t->tv_usec=1000*timebuffer.millitm; return 0; } clock_t times (struct tms *__buffer) { __buffer->tms_utime = clock(); __buffer->tms_stime = 0; __buffer->tms_cstime = 0; __buffer->tms_cutime = 0; return __buffer->tms_utime; }
Skip to content
Navigation Menu
Provide feedback
Saved searches
Use saved searches to filter your results more quickly
Sign up
Appearance settings
header-only Windows implementation of the <sys/time.h>
header.
tested on the following compilers:
- Visual Studio
- Clang for Windows (clang-cl)
- GCC (MinGW)
defines the following structures:
- timeval
implements the following functions:
- gettimeofday
Hey there, fellow coder! Have you ever found yourself in a scenario where you’re all set to build a cross-platform application using your all-time favorite tool, Visual C++, and suddenly you bump into a hiccup with timing functions? Yep, I’m talking about that moment when you need to use sys/time.h
in Windows and realize it’s not quite there where you’d expect it. But don’t worry, we’re here to untangle this little conundrum together.
The Crux of the Problem
Imagine this. You’re excitedly looking to measure time intervals in your app using sys/time.h
, which is quite handy in Unix-based systems. But then you find it missing in plain sight when working on Windows. Perhaps you intended to calculate precise durations for performance monitoring or to timestamp events, only to find one small but significant bump on the Windows road.
This is a common issue we run into when venturing into cross-platform development. Understanding time-keeping across different systems can feel like a puzzle. But like a puzzle, it’s nothing we can’t solve with the right pieces.
Walking Through the Solution
Let’s crack open the shell here. The consensus within the development community comes down to a two-fold approach: replicate the required functionality or employ alternatives.
Approach 1: Custom Implementation
How about crafting your own version of the functionality? It might seem daunting, but it provides control and can be kind of rewarding too. Here’s a way to mimic gettimeofday()
using Windows-specific APIs:
#include <windows.h>
int gettimeofday(struct timeval* tp, struct timezone* tzp) {
FILETIME ft;
__int64 tmpres = 0;
static const __int64 DELTA_EPOCH_IN_MICROSECS = 11644473600000000;
if (NULL != tp) {
GetSystemTimeAsFileTime(&ft);
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
// Convert to microseconds
tmpres /= 10;
// Convert to Unix epoch time
tmpres -= DELTA_EPOCH_IN_MICROSECS;
tp->tv_sec = (long)(tmpres / 1000000UL);
tp->tv_usec = (long)(tmpres % 1000000UL);
}
return 0;
}
Here, we’re using GetSystemTimeAsFileTime()
to grab the current system time, followed by conversions to obtain a format akin to Unix’s epoch time. Easy-peasy, right?
Approach 2: Embracing Alternatives
Another route you might consider is using alternatives such as QueryPerformanceCounter()
and QueryPerformanceFrequency()
. Here’s a sneak peek:
#include <windows.h>
double PCFreq = 0.0;
__int64 CounterStart = 0;
void StartCounter() {
LARGE_INTEGER li;
if (!QueryPerformanceFrequency(&li))
std::cerr << "QueryPerformanceFrequency failed!\n";
PCFreq = double(li.QuadPart) / 1000.0;
QueryPerformanceCounter(&li);
CounterStart = li.QuadPart;
}
double GetCounter() {
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
return double(li.QuadPart - CounterStart) / PCFreq;
}
This alternative takes advantage of Windows’ performance counters to mark precise intervals, offering precision that may suit your needs beautifully.
Tying It All Up
Time management – both in life and in code – isn’t always straightforward. Especially so when juggling between different systems like Linux and Windows. However, with the nifty tricks we’ve explored today, you should be well-prepared to tackle the absence of sys/time.h
on Windows.
Now, you can craft solutions tailored to your project’s specific demands. Experimentation is key, so get in there and mix things up! Remember, each project has its rhythm, and finding the right timing solution will make sure your code waltzes smoothly. Cheers to keen coding insights and friendly community exchanges!
В этом посте будет обсуждаться, как найти время выполнения программы C в средах Windows и Linux.
Существует четыре широко используемых метода определения времени выполнения программы на C:
1. Использование clock()
функция
Мы можем использовать clock()
функция, предоставляемая <time.h>
заголовочный файл для расчета времени ЦП, потребляемого задачей в приложении C. Он возвращает clock_t
type, в котором хранится общее количество тактов часов.
Чтобы вычислить общее количество прошедших секунд, нам нужно разделить общее количество прошедших тактов часов на CLOCKS_PER_SEC
макрос (также присутствует в <time.h>
) как показано ниже:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#include <stdio.h> #include <time.h> // for clock_t, clock(), CLOCKS_PER_SEC #include <unistd.h> // for sleep() // основная функция для определения времени выполнения программы на C int main() { // для хранения времени выполнения кода double time_spent = 0.0; clock_t begin = clock(); // делаем здесь что-нибудь sleep(3); clock_t end = clock(); // рассчитать прошедшее время, найдя разницу (end — begin) и // деление разницы на CLOCKS_PER_SEC для перевода в секунды time_spent += (double)(end — begin) / CLOCKS_PER_SEC; printf(«The elapsed time is %f seconds», time_spent); return 0; } |
Скачать Выполнить код
Выход (может варьироваться):
The elapsed time is 0.000014 seconds
Обратите внимание, что clock()
Функция не возвращает фактическое количество прошедшего времени, а возвращает количество времени, которое потребовалось базовой операционной системе для запуска процесса. Другими словами, фактическое время настенных часов может быть намного больше.
2. Использование time()
функция
The <time.h>
заголовок также предоставляет time()
функция, которая возвращает общее количество секунд, прошедших с начала Эпохи (00:00:00 UTC, 1 января 1970 г.). Он принимает указатель на time_t
в качестве аргумента, который обычно передается как NULL
и возвращает time_t
тип. Если аргумент не NULL
, то возвращаемое значение также сохраняется в памяти, на которую указывает аргумент.
Его использование аналогично clock()
функцию, как показано ниже:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include <stdio.h> #include <time.h> // for time() #include <unistd.h> // for sleep() // основная функция для определения времени выполнения программы на C int main() { time_t begin = time(NULL); // делаем здесь что-нибудь sleep(3); time_t end = time(NULL); // вычислить прошедшее время, найдя разницу (end — begin) printf(«The elapsed time is %d seconds», (end — begin)); return 0; } |
Скачать Выполнить код
результат:
The elapsed time is 3 seconds
3. Использование gettimeofday()
функция
The gettimeofday()
Функция возвращает время настенных часов, прошедшее с начала эпохи, и сохраняет его в timeval
структура, выраженная в секундах и микросекундах.
Он определен в <sys/time.h>
заголовочный файл и принимает два аргумента — первый аргумент является ссылкой на timeval
структура, а второй аргумент — нулевой указатель. timeval
структура объявляется следующим образом: <time.h>
заголовок:
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
Следующий код демонстрирует использование gettimeofday()
путем измерения времени настенных часов:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include <stdio.h> #include <sys/time.h> // for gettimeofday() #include <unistd.h> // for sleep() // основная функция для определения времени выполнения программы на C int main() { struct timeval start, end; gettimeofday(&start, NULL); // делаем здесь что-нибудь sleep(5); gettimeofday(&end, NULL); long seconds = (end.tv_sec — start.tv_sec); long micros = ((seconds * 1000000) + end.tv_usec) — (start.tv_usec); printf(«The elapsed time is %d seconds and %d micros\n», seconds, micros); return 0; } |
Скачать Выполнить код
Выход (может варьироваться):
The elapsed time is 5 seconds and 5000147 micros
Эта функция поддерживается компиляторами GCC и может не работать в Windows.
4. Использование clock_gettime()
функция
Мы также можем использовать clock_gettime()
функция, определенная в <time.h>
заголовочный файл, который поддерживает точность до наносекунд. Он принимает два аргумента: первый аргумент — это тип часов, а второй аргумент — указатель на timespec
структура. timespec
структура обеспечивается <time.h>
заголовок и объявляется как:
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
Следующий код вычисляет прошедшее время, используя общесистемные часы реального времени, обозначенные как CLOCK_REALTIME
, время которого представляет секунды и наносекунды с начала Эпохи.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#include <stdio.h> #include <time.h> // for clock_t, clock() #include <unistd.h> // for sleep() #define BILLION 1000000000.0 // основная функция для определения времени выполнения программы на C int main() { struct timespec start, end; clock_gettime(CLOCK_REALTIME, &start); // делаем здесь что-нибудь sleep(3); clock_gettime(CLOCK_REALTIME, &end); // time_spent = конец — начало double time_spent = (end.tv_sec — start.tv_sec) + (end.tv_nsec — start.tv_nsec) / BILLION; printf(«The elapsed time is %f seconds», time_spent); return 0; } |
Скачать код
Обратите внимание, что clock_gettime()
будет работать только на очень немногих машинах UNIX.
Вот и все, что касается нахождения времени выполнения программы на C.
Связанный пост:
Измерьте прошедшее время программы C++ с помощью библиотеки Chrono
sys/time.h(1)
time types
SYNOPSIS
#include <sys/time.h>
DESCRIPTION
The <sys/time.h> header shall define the timeval structure
that includes at least the following members:
-
time_t tv_sec Seconds. suseconds_t tv_usec Microseconds.
The <sys/time.h> header shall define the itimerval structure
that includes at least the following
members:
-
struct timeval it_interval Timer interval. struct timeval it_value Current value.
The time_t and suseconds_t types shall be defined as described
in <sys/types.h> .
The fd_set type shall be defined as described in <sys/select.h>
.
The <sys/time.h> header shall define the following values for
the which argument of getitimer() and setitimer():
- ITIMER_REAL
- Decrements in real time.
- ITIMER_VIRTUAL
- Decrements in process virtual time.
- ITIMER_PROF
-
Decrements both in process virtual time and when the system is running
on behalf of the process.
The following shall be defined as described in <sys/select.h>
: FD_CLR() FD_ISSET() FD_SET() FD_ZERO() FD_SETSIZE
The following shall be declared as functions and may also be defined
as macros. Function prototypes shall be provided.
-
int getitimer(int, struct itimerval *); int gettimeofday(struct timeval *restrict, void *restrict); int select(int, fd_set *restrict, fd_set *restrict, fd_set *restrict, struct timeval *restrict); int setitimer(int, const struct itimerval *restrict, struct itimerval *restrict); int utimes(const char *, const struct timeval [2]); (LEGACY )
Inclusion of the <sys/time.h> header may make visible all symbols
from the <sys/select.h> header.
The following sections are informative.
COPYRIGHT
Portions of this text are reprinted and reproduced in electronic form
from IEEE Std 1003.1, 2003 Edition, Standard for Information Technology
— Portable Operating System Interface (POSIX), The Open Group Base
Specifications Issue 6, Copyright (C) 2001-2003 by the Institute of
Electrical and Electronics Engineers, Inc and The Open Group. In the
event of any discrepancy between this version and the original IEEE and
The Open Group Standard, the original IEEE and The Open Group Standard
is the referee document. The original Standard can be obtained online at
http://www.opengroup.org/unix/online.html .