• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Funkcje typu Sleep usypiają na dłużej niż powinny

Object Storage Arubacloud
0 głosów
196 wizyt
pytanie zadane 8 czerwca 2019 w C i C++ przez AuriattaDev Początkujący (390 p.)
zamknięte 8 czerwca 2019 przez AuriattaDev
Hej,
Gdy odpalam program na lapku, funkcja Sleep(1) spowalnia się na jakieś 50/100 ms.
Nie zawsze tak jest i niekiedy działa prawidłowo. Procesor i ram w obu przypadkach nie jest przeciążony.
Jest także podłączony do zasilania.
Na początku wydawało mi się że to wina jakiegoś frameworka, teraz to już w ogóle nie wiem.

Używałem dotychczas:
Sleep(1);
this_thread::sleep_for(chrono::nanoseconds(1000000));

Wie może czym może być spowodowany ten niecodzienny błąd?
 

PS: jest to nowy laptop z processorem i5-8250U i 16gb pamięci
komentarz zamknięcia: Problem rozwiązany

1 odpowiedź

+1 głos
odpowiedź 8 czerwca 2019 przez adrian17 Ekspert (344,860 p.)
edycja 8 czerwca 2019 przez adrian17
 
Najlepsza

sleep_for()/Sleep()/sleep() to nie jest dokładny timer - mówi tylko "uśpij mnie na X czasu i wzbudź gdy będziesz mógł".

https://en.cppreference.com/w/cpp/thread/sleep_for

This function may block for longer than sleep_duration due to scheduling or resource contention delays.

https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-sleep

The system clock "ticks" at a constant rate. If dwMilliseconds is less than the resolution of the system clock, the thread may sleep for less than the specified length of time. If dwMilliseconds is greater than one tick but less than two, the wait can be anywhere between one and two ticks, and so on

Note that a ready thread is not guaranteed to run immediately. Consequently, the thread may not run until some time after the sleep interval elapses.

(zważ też, że jeśli próbujesz używać go cyklicznie jako "zegar", to do czasu "zegara" trzeba doliczyć czas działania Twojego programu)

komentarz 8 czerwca 2019 przez AuriattaDev Początkujący (390 p.)
Dzięki za info, jedyne co mi przychodzi do głowy to pusta pętla na bazie licznika systemowego. Choć obawiam się że to zeżre procek.
Czy może polecasz jakiś bardziej precyzyjny "Delay"?
komentarz 8 czerwca 2019 przez j23 Mędrzec (194,920 p.)
Może powiedz, po co Ci taki dokładny delay.
komentarz 8 czerwca 2019 przez AuriattaDev Początkujący (390 p.)

Gdy wypisuje na ekranie literki za pomocą cout.
By okno programu przesuwało się płynnie i za każdym razem tak samo:
 

for (int i = -(sizex / 3); i < -1; i += WindowPX_Offset)
    {
        MoveWindow(GetConsoleWindow(), i, 20, sizex / 4, sizey / 2, TRUE);

       //delay
    }


Bądź gdy program czeka na klawisz, by nie zżerało cpu:
 

while(true)
{
		if (GetAsyncKeyState(VK_LCONTROL) & 0x8000)
		{
			break
		}
//delay
}

^ ^

komentarz 8 czerwca 2019 przez j23 Mędrzec (194,920 p.)

Przecież w pierwszej pętli nie potrzeba aż takiej dokładności, +-20ms nie zrobi różnicy (AFAIK w Windowsie dokładność to jakieś 10ms). Zresztą możesz kompensować opóźnienia. W drugiej wystarczy Sleep(1).

komentarz 8 czerwca 2019 przez AuriattaDev Początkujący (390 p.)
U mnie dokładność czasu = szybkość, dlatego jest taka istotna.
Dla mnie ważne jest by czas delay był stały.
Raz się okazuje że efekt jest za wolny a po jakimś czasie za szybki.

W pętli "klawiszowej" chyba faktycznie wystarczy sleep.
komentarz 8 czerwca 2019 przez j23 Mędrzec (194,920 p.)

Dlatego kompensuje się takie opóźnienia. Na systemach takich jak Windows czy Linux nie uzyskasz dużych dokładności, bo systemowy planista musi rozdzielić czas procesora na kilkadziesiąt innych procesów, więc siłą rzeczy dokładność Sleep zależy od obciążenia CPU. Samo MoveWindow może się wykonywać za każdym razem w różnym czasie.

komentarz 8 czerwca 2019 przez AuriattaDev Początkujący (390 p.)
Pierwszy raz słyszę o kompensacji opóźnień.
Mógł byś podać odpowiednik w angielskim?
1
komentarz 8 czerwca 2019 przez adrian17 Ekspert (344,860 p.)
edycja 8 czerwca 2019 przez adrian17
Możesz zmierzyć czas jaki faktycznie upłynął i na jego podstawie albo odpowiednio skrócić lub wydłużyć następnego sleepa, albo wziąć zmienny czas pod uwagę przy obliczaniu cokolwiek Twoja aplikacja liczy.
1
komentarz 8 czerwca 2019 przez j23 Mędrzec (194,920 p.)

Czyli mogłoby to wyglądać tak:

using namespace std::chrono_literals;

std::chrono::milliseconds interval = 100ms;

for (int i = -(sizex / 3); i < -1; i += WindowPX_Offset) {
	auto t1 = std::chrono::steady_clock::now();
	
	MoveWindow(GetConsoleWindow(), i, 20, sizex / 4, sizey / 2, TRUE);
	
	auto t2 = std::chrono::steady_clock::now();
	
	std::chrono::milliseconds sleep_time = interval - std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1);
	if (sleep_time.count() <= 0) continue;
	std::this_thread::sleep_for(sleep_time);
}

Samo sleep_for też możesz sprawdzać, czy się nie spóźniło i wtedy uwzględnić to w przesunięciu okna.

komentarz 8 czerwca 2019 przez AuriattaDev Początkujący (390 p.)
Aa rozumiem, faktycznie Adrian.

Czaje j23, potetuję, zobaczę jak to będzie z nanosekundami hah.

Rozwiązanie idealne, dzięki chłopaki : )

Podobne pytania

0 głosów
1 odpowiedź 235 wizyt
pytanie zadane 27 marca 2016 w C i C++ przez niezalogowany
0 głosów
1 odpowiedź 229 wizyt
0 głosów
1 odpowiedź 145 wizyt
pytanie zadane 17 kwietnia 2018 w PHP przez kevin Mądrala (5,010 p.)

92,555 zapytań

141,403 odpowiedzi

319,557 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...