[C++] Funkcja która czeka na zmiane danych


(Kalin 93) #1

Witam.

Interesuje mnie funkcja ktore oczekuje aż jakieś dane się zmienią.

Można by użyć :

for (;;)

{

if (warunek)break;

}

Tylko ze taka funkcja używa procesora w 100%

Czy jest jakiś odpowiednik który by był oszczędniejszy ? :slight_smile:

PS. Nie mówie o _sleep bo chodzi o uaktualnienie w czasie rzeczywistym


(Sawyer47) #2

Może to nie dokładnie to o co Ci chodzi, ale możesz spróbować użyć sygnałów, to już zależy od konkretnego problemu.

Zobacz np. sigc++ http://libsigc.sourceforge.net/doc.shtml lub Boost.Signals: http://www.boost.org/doc/libs/1_36_0/do ... gnals.html

Kiedy dane się zmienią można wysłać sygnał i obserwatorzy zostaną o tym powiadomieni.


(system) #3

Pod windows'ami rozwiązaniem jest:

for(;;) if(warunek) break; else Sleep(5000); // sprawdza co 5 sek

albo funkcje API:

WaitForSingleObject() oraz kilka innych z funkcją tą związane w zależności od tego co sprawdzasz.

Pod unux'em też jest sleep() tylko z malej litery i też jest odpowiednik WaitForSingleObject() tylko nie pamiętam jak się nazywa i nie mam teraz dostępu do man'a aby sprawdzić.


(Kalin 93) #4

Chodzi mi bardziej o cos takiego ze np:

zmienia sie czas systemowy do określonej wartości i wtedy następuje wykonanie instrukcji/funkcji istnieje cos takiego ?

13tySmok ,


(Sawyer47) #5

Podaj dokładniejszy opis problemu, może jakiś kod, który już masz? Możesz użyć albo sygnału albo sleep, inne rozwiązanie na razie nie przychodzi mi do głowy.


(system) #6

W windows'ach możesz ustawić callback'a na zmiane danych systemowych. Jeżeli zaś szukasz wykonania czegoś o określonym czasie, to może użyj TTimer. Może najpierw powiesz przynajmniej o który system ci chodzi, windows czy unix?


(Kalin 93) #7

Oczywiście Windows zaraz poczytam o tym o czym mówił 13tySmok. Mam w planach napisać sobie programik (konsolowy) który dawałby możliwość np zamykania systemu o określonej godzinie lub warunku

EDIT : http://www.codeguru.com/cpp/cpp/cpp_mfc/callbacks/article.php/c4129/ mógłby ktoś mi wytłumaczyć jak to działa bo jakoś nie moge załapać


(system) #8

Hmmm, w systemie już to jest. Polecenie shutdown z różnymi opcjami, oraz scheduler.


(Kalin 93) #9

Tak , to wiem ale np scheduler nie zamknie procesu.


(system) #10

Jeżeli o określonej porze odpali shutdown.exe to masz to co chcesz.


(Kalin 93) #11

A tak z ciekawości , wiesz może jak wyczyścić bufor w kbhit() ?


(system) #12

kbhit() nie ma bufora. Jest bufor systemowy (BIOS'a) dopóki kbhit() zwraca nie zero pobierasz znak za pomocą np. getch(), czyli jedna pętla while.


(Kalin 93) #13
#include 

#include 


using namespace std;


int nZnak;


int main ()

{

    for (;;)

    {

        cout << "\a" ;

        if (kbhit ())

        {

                  nZnak = getch ();

                  if (nZnak == 27)

                  {

                            return 0;

                  };

        };

        _sleep (500);

    };

}

Mógłbyś mi pokazać na tym kodzie jak to zrobić ?


(Fiołek) #14
while(kbhit() != 0)

{

   getch();

}

Zanim znowu zadasz takie pytanie, pomyśl.


(Kalin 93) #15

No nie działa niestety , spróbuj wcisnąć najpierw kilka klawiszy a dopiero potem ESC


(system) #16

Miałem na myśli:

while(kbhit()) getch();

Z kodu który pokazałeś nie zbyt wynika czego chcesz osiągnąć. Zakładam że po sygnale dźwiękowym użytkownik ma nacisnąć ESC, jeżeli nie naciśnie ESC to znowu dostaję dźwięk, jeżeli założenie jest słuszne :smiley: to:

#include 

#include 


using namespace std;


int main ()

  {

   for(;;)

     {

      cout<<'\a'; // niema co dawać ciąg znaków jeżeli drukujesz jeden znak.

/*

      while(kbhit())

        {

         int nZnak=getch(); // zmienne najlepiej deklarować tam gdzie potrzebne, wystrzegając się globalnych.

         if(nZnak==27) return 0; // po if nie jest potrzebny średnik jeżeli ma jedną instrukcje to nie potrzebne również klamerki

        }

*/

      while(kbhit()) if(getch()==27) return 0; // wszystko co w komentarze można zapisać właśnie tak 

      _sleep(500);

     } // po for nie jest potrzebny średnik

  }

A może ci wystarczy jedynie cin.ignore(); ? Napisz dokładnie co chcesz osiągnąć.


(Kalin 93) #17

No dokładnie to co napisałeś . Sygnał dźwiękowy ma być powtarzany w nieskończoność do póki nie zostanie naciśnięty klawisz ESC :slight_smile:


(system) #18

To może lepiej tak:

#include 


int main ()

  {

   for(;;)

     {

      putchar('\a'); // nie należy mieszać asynchroniczne i synchroniczne we/wy.

      _sleep(500); // sleep przed oczekiwaniem na naciśnięcie aby użyszkodnik zdążył zareagować

      while(kbhit()) if(getch()==27) return 0;

     }

  }

(Kalin 93) #19

Teraz działa :slight_smile: tylko nie rozumiem dlaczego musi być

while(kbhit())

a nie

if(kbhit())

jakoś nie mogę tego pojąć :slight_smile:


(system) #20

Ponieważ w czasie tych pół sekundy użyszkodnik mógł wcisnąć więcej niż jeden przycisk. Więc jeżeli zamienisz na if a użytkownik wciśnie 3 przyciski (nie ESC) a potem ESC to dostanie jeszcze 3 razy dźwięk zanim program zareaguje na ten ESC.