2009-05-21 16 views
11

Podczas oczekiwania na niesygnalizowane zdarzenie przy użyciu funkcji WaitForSingleObject, stwierdzam, że w niektórych przypadkach wywołanie zwróci wartość CZAS_STRONY_OSTRONTU w czasie krótszym niż określony limit czasu. Po prostu zapętlając połączenie z limitem czasu ustawionym na 1000ms, widziałem powrót połączenia w okresach tak niskich jak 990ms (uruchomionych na WinXP). Używam QueryPerformanceCounter, aby uzyskać niezależny od zegara systemowego pomiar czasu, więc nie sądzę, że dryf zegara prawdopodobnie będzie odpowiedzią.Limit czasu oczekiwania WaitForSingleObject

To zachowanie nie stanowi dla mnie żadnych praktycznych problemów, ale chciałbym go lepiej zrozumieć. Wygląda na to, że może działać z mniej więcej rozdzielczością znacznika czasu. Czy firma Microsoft publikuje dalsze szczegóły dotyczące dokładności tej funkcji? Czy powinienem oczekiwać większej precyzji w Vista?

+0

Chciałbym zasugerować mały test: po prostu wstaw "sleep (0)" przed funkcją wait. Jest bardzo prawdopodobne, że zmieni to zachowanie, aby spełnić Twoje oczekiwania. Również: Konwersja wyników 'QueryPerformanceCounter()' na wartości czasu przy użyciu częstotliwości zwracanej przez 'QueryPerformanceFrequency()' oznacza, że ​​częstotliwość jest precyzyjna. Podana częstotliwość jest traktowana jako stała. Ale nietrafiony sprzęt ma tolerancje. Częstotliwość zawsze ma przesunięcie, a nawet dryf termiczny. – Arno

Odpowiedz

8

Tak, obiekt WaitForSingleObject używa rozdzielczości znacznika czasu, nie używa zegara o wysokiej rozdzielczości, takiego jak QueryPerformanceCounter.

http://msdn.microsoft.com/en-us/library/ms687069(VS.85).aspx, artykuł MSDN na „Wait Functions” rozszerza się na to:

Dokładność określonego limitu czasu przedziału zależy od rozdzielczości zegara systemowego. Zegar systemowy "zaznacza" ze stałą prędkością. Jeśli interwał limitu czasu wynoszący jest mniejszy niż rozdzielczość zegara systemowego, oczekiwanie na czas oczekiwania może trwać krócej niż określony czas . Jeśli przedział limitu czasu wynoszący jest większy niż jeden przedział , ale mniejszy niż dwa, czas oczekiwania może wynosić gdziekolwiek pomiędzy jednym a dwoma znacznikami, i tak dalej.

W tym artykule wyjaśniono także, jak używać timeBeginPeriod do zwiększania rozdzielczości zegara systemowego - ale nie jest to zalecane.

Mogę wymyślić kilka powodów. Po pierwsze, wyższa rozdzielczość nie jest potrzebna w prawie wszystkich przypadkach użycia WaitForSingleObject. Użycie timera o wysokiej rozdzielczości wymagałoby ciągłego odpytywania licznika przez kernel (nie jest to wykonalne, ponieważ nie zawsze gwarantuje się, że kod jądra zawsze działa) lub przeprogramowania go często w celu wygenerowania przerwania (ponieważ może istnieć wiele obiektów WaitForSingleObjects i najprawdopodobniej tylko jeden programowalne przerwanie).

Z drugiej strony, istnieje już źródło taktowania, które jest stale aktualizowane w rozdzielczości, która jest wystarczająco dobra dla WaitForSingleObject, SetWaitableTimer i Sleep.

Powiązane problemy