我应该用什么来替换 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 06:53:03  来源:igfitidea点击:

What should I use to replace gettimeofday() on Windows?

windowsselectwinapigettimeofday

提问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 timevalfor 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 0at 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。这些分辨率非常高——在某些硬件定时器上低至每十个周期一个滴答。