我应该用什么来替换 Windows 上的 gettimeofday()?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1676036/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What should I use to replace gettimeofday() on Windows?
提问by dicroce
I'm writing a portable Socket class that supports timeouts for both sending and receiving... To implement these timeouts I'm using select()
.... But, I sometimes need to know how long I was blocked inside select()
which of course on Linux I would implement by calling gettimeofday()
before and after I call select()
and then using timersub()
to calculate the delta...
我正在编写一个可移植的 Socket 类,它支持发送和接收的超时......为了实现我正在使用的这些超时select()
......但是,我有时需要知道我被阻塞了多长时间select()
,当然在 Linux 上我将通过gettimeofday()
在我调用之前和之后调用select()
然后timersub()
用于计算增量来实现...
Given that select()
on Windows accepts struct timeval
for it's timeout, what method should I used to replace gettimeofday() on Windows?
鉴于select()
在 Windows 上接受struct timeval
它的超时,我应该使用什么方法来替换 Windows 上的 gettimeofday()?
回答by dicroce
I ended up finding this page: gettimeofday()
function for Windows(now via the Wayback Machine) which has a handy, dandy implementation of gettimeofday()
on Windows. It uses the GetSystemTimeAsFileTime()
method to get an accurate clock.
我最终找到了这个页面:gettimeofday()
Windows 的函数(现在通过 Wayback Machine),它gettimeofday()
在 Windows 上有一个方便、漂亮的实现。它使用该GetSystemTimeAsFileTime()
方法来获得准确的时钟。
Update: Here's an alternative active link from the 'Unix to Windows Porting Dictionary for HPC' gettimeofday()
(now via the Wayback Machine) that points to the implementation the OP referred to. Note also that there's a typo in the linked implementation:
更新:这是“用于 HPC 的 Unix 到 Windows 移植字典” gettimeofday()
(现在通过 Wayback 机器)的替代活动链接, 它指向 OP 所指的实现。另请注意,链接实现中有一个错字:
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 // WRONG
#else
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL // WRONG
#endif
The values shown are missing an extra 0
at the end (they assumed microseconds, not the number of 100-nanosecond intervals). This typo was found via this commenton a Google code project page. The correct values to use are shown below:
显示的值0
最后缺少一个额外的值(它们假定为微秒,而不是 100 纳秒间隔的数量)。这个错字是通过谷歌代码项目页面上的这个评论发现的。要使用的正确值如下所示:
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS 116444736000000000Ui64 // CORRECT
#else
#define DELTA_EPOCH_IN_MICROSECS 116444736000000000ULL // CORRECT
#endif
PostgreSQL's implementation of gettimeofday for Windows:
PostgreSQL 对 Windows 的 gettimeofday 的实现:
/*
* gettimeofday.c
* Win32 gettimeofday() replacement
*
* src/port/gettimeofday.c
*
* Copyright (c) 2003 SRA, Inc.
* Copyright (c) 2003 SKC, Inc.
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose, without fee, and without a
* written agreement is hereby granted, provided that the above
* copyright notice and this paragraph and the following two
* paragraphs appear in all copies.
*
* IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT,
* INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
* LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
* DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS
* IS" BASIS, AND THE AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE,
* SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#include "c.h"
#include <sys/time.h>
/* FILETIME of Jan 1 1970 00:00:00. */
static const unsigned __int64 epoch = ((unsigned __int64) 116444736000000000ULL);
/*
* timezone information is stored outside the kernel so tzp isn't used anymore.
*
* Note: this function is not for Win32 high precision timing purpose. See
* elapsed_time().
*/
int
gettimeofday(struct timeval * tp, struct timezone * tzp)
{
FILETIME file_time;
SYSTEMTIME system_time;
ULARGE_INTEGER ularge;
GetSystemTime(&system_time);
SystemTimeToFileTime(&system_time, &file_time);
ularge.LowPart = file_time.dwLowDateTime;
ularge.HighPart = file_time.dwHighDateTime;
tp->tv_sec = (long) ((ularge.QuadPart - epoch) / 10000000L);
tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
return 0;
}
回答by knight666
How about:
怎么样:
unsigned long start = GetTickCount();
// stuff that needs to be timed
unsigned long delta = GetTickCount() - start;
GetTickCount()
is not very precise, but will probably work well. If you see a lot of 0, 16 or 31 millisecond intervals, try timing over longer intervals or use a more precise function like timeGetTime
.
GetTickCount()
不是很精确,但可能会很好地工作。如果您看到很多 0、16 或 31 毫秒的间隔,请尝试在更长的间隔内计时或使用更精确的函数,例如timeGetTime
.
What I usually do is this:
我通常做的是这样的:
unsigned long deltastack;
int samples = 0;
float average;
unsigned long start = GetTickCount();
// stuff that needs to be timed
unsigned long delta = GetTickCount() - start;
deltastack += delta;
if (samples++ == 10)
{
// total time divided by amount of samples
average = (float)deltastack / 10.f;
deltastack = 0;
samples = 0;
}
回答by Shay Erlichmen
In your case I would use the platform independent std::clock
在你的情况下,我会使用平台独立的std::clock
回答by Puppy
You can check out QueryPerformanceCounter and QueryPerformanceFrequency. These are veryhigh resolution- down to one tick per ten cycles on some hardware- timers.
您可以查看 QueryPerformanceCounter 和 QueryPerformanceFrequency。这些分辨率非常高——在某些硬件定时器上低至每十个周期一个滴答。