Odliczanie czasu, stoper

0

Witam, taj jak napisałem w temacie chodzi mi o program odmierzający czas, coś w rodzaju stopera. znalazłem w necie informację że funkcja sleep(x) wykonuje opóźnienie o czas podany jako argument w ms. Napisałem taki prosty program:

 #include<stdio.h>

main(){
       int h, m, s, ss;
       for(h=0, m=0, s=0, ss=0;;ss++){
                         sleep(1);
                         system("cls");
                         if(ss==1000){
                                     s++;
                                     ss=0;
                                     }
                         printf("%2d: %2d: %2d: %2d\n", h, m, s, ss);
                         }
       getch();
       }

ale czas o jaki opóźnia funkcja to nie jest 1000ms czyli 1s. Zanim zmienna s (w moim przypadku założyłem że reprezentuje ona sekundy) zwiększy się o 1 mija niewiele ponad 30s. Mógł by ktoś wyjaśnić dlaczego tak się dzieje i jak napisać pętlę odliczającą mili sekundy?

0

Więcej tabów dać się nie dało?

0

rozdzielczość sleep wynosi 3600s/65536, czyli około 18.2ms.
chcesz spać jedną sekundę, to śpij jedną sekundę.
ponadto zauważ, że tysiąc razy wykonujesz system("cls"), które też zajmuje pewną ilość czasu, im wolniejszy procesor tym większą.

użyj timera, jeśli chcesz wykonywać coś w miarę precyzyjnie co pewien czas. przy czym timer też nie jest dokładny, bo obarczony tym samym błędem, co sleep, a system nie gwarantuje, że timer będzie "cykać" dokładnie co sekundę - w końcu windows i linuks to nie są systemy czasu rzeczywistego. timer da Ci to, że jeśli podczepiony pod niego kod wykonuje się krócej niż interwał timera, to nie będzie wpływał na błąd "cyknięcia". ponadto timer nie będzie blokować całego programu - obsługa cyknięcia wykonuje się asynchronicznie.
ponadto nie polegaj na tym, że 60 cyknięć timera co 1000ms da 60s - ani sleep, ani timer nie gwarantuje tego. wystarczy pełne obciążenie wszystkich rdzeni przez wątki z wyższym priorytetem, żeby timer bardzo zwolnił, a sleep bardzo się wydłużył.

podsumowując - jeśli potrzebujesz rozdzielczości rzędu sekundy, to dawaj sleep/interwał timera tego samego rzędu wielkości i nigdy nie polegaj na ich dokładności .

0

jeszcze odpowiadając na Twoje pytanie - tysiąc klatek na sekundę jeszcze długo będzie nierealne. na komputerze pewnie masz odświeżanie ekranu ustawione na 60Hz, czyli 60fps (klatek na sekundę) i nie ma sensu odświeżać częściej, bo tylko marnujesz zasoby cpu. 60Hz ~ 17ms. w praktyce zrealizujesz to dając timer lub sleep o takim (albo i dłuższym) czasie, a przy wyświetlaniu pobierając datę systemową. data jest brana ze sprzętowego zegara systemowego, który pomyka w czasie rzeczywistym (jednak AFAIR z interwałem 1h/65536) i zwykle Cię nie oszuka, nawet jeśli timer zacznie cykać co 10s zamiast co 17ms

1 użytkowników online, w tym zalogowanych: 0, gości: 1