2009-11-04 15 views
15

Piszę przenośną klasę Socket, która obsługuje limity czasu dla wysyłania i odbierania ... Aby zaimplementować te limity czasu używam select() .... Ale czasami muszę wiedzieć, jak długo byłem zablokowany wewnątrz select(), który z Oczywiście na Linuksie chciałbym realizować poprzez wywołanie gettimeofday() przed i po wzywam select() a następnie za timersub() obliczyć deltę ...Co należy użyć, aby zastąpić gettimeofday() w systemie Windows?

Biorąc pod uwagę, że w systemie Windows akceptuje select()struct timeval na to czas oczekiwania, jaka metoda powinna kiedyś zastąpić gettimeofday () w systemie Windows?

Odpowiedz

18

skończyło się znalezieniem tej strony internetowej: gettimeofday() w systemie Windows [edit: link usunięty, ponieważ teraz wskazuje na witrynę reklamową]. Który ma poręczną, dandysową implementację gettimeofday() w systemie Windows. Używa metody GetSystemTimeAsFileTime(), aby uzyskać dokładny zegar.

Aktualizacja: Oto aktywny link [edytuj: link usunięty, ponieważ teraz wskazuje na witrynę reklamową], który wskazuje na wdrożenie, do którego odnosi się PO. Należy również zauważyć, że nie jest to literówka w połączonej realizacji:

#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) 
    #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 // WRONG 
#else 
    #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL // WRONG 
#endif 

Wartości podane brakuje dodatkowego 0 na końcu (zakładali mikrosekund, a nie liczba odstępach 100-nanosekundowych). Ta literówka została znaleziona przez this comment na stronie projektu Google code. Prawidłowe wartości do wykorzystania pokazano poniżej: wdrożenie

#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) 
    #define DELTA_EPOCH_IN_MICROSECS 116444736000000000Ui64 // CORRECT 
#else 
    #define DELTA_EPOCH_IN_MICROSECS 116444736000000000ULL // CORRECT 
#endif 

PostgreSQL z gettimeofday dla okien:

/* 
* 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; 
} 
+11

Link jest zepsuty. –

+1

Drugi link również jest teraz uszkodzony. – Tom

+0

Oto link do odpowiedniego kodu z PostgreSQL: http://git.postgresql.org/gitweb/?p=postgresql.git; a = blob; f = src/port/gettimeofday.c; h = 75a91993b74414c0a1c13a2a09ce739cb8aa8a08; hb = HEAD – Tom

4

Jak o:

unsigned long start = GetTickCount(); 
// stuff that needs to be timed 
unsigned long delta = GetTickCount() - start; 

GetTickCount() nie jest bardzo precyzyjny, ale prawdopodobnie będzie działać dobrze. Jeśli widzisz wiele przedziałów 0, 16 lub 31 milisekund, spróbuj mierzyć czas w dłuższych odstępach czasu lub użyj bardziej precyzyjnej funkcji, takiej jak timeGetTime.

Co zwykle zrobić to:

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; 
} 
+3

Rolowanie na GetTicksCount co 45.7 dni. –

+11

@Shay: Kiedy widziałeś Windows przez ponad 45 dni prosto? OK, tak, było to niefortunne dla ... –

+0

[Funkcja GetTickCount] (https://msdn.microsoft.com/pt-br/library/windows/desktop/ms724408%28v=vs.85%29.aspx) - Retrieves liczba milisekund, które upłynęły od uruchomienia systemu, do 49,7 dni. – Dinei

1

W twoim przypadku użyłbym platformę niezależną std::clock

+0

Ta funkcja nie zwraca bezwzględnego odniesienia do czasu. – chmike

+0

@chmike nie powiedział, że potrzebuje bezwzględnego odniesienia czasowego –

1

Możesz sprawdzić QueryPerformanceCounter i QueryPerformanceFrequency. Są to: very wysoka rozdzielczość - do jednego tiknięcia na dziesięć cykli w niektórych sprzętowych przekaźnikach czasowych.

Powiązane problemy