Sven: Ständige Aktualisierung im Programm erzwingen

Hallo,

erstmal Sorry das ich nochmal mit meiner C Programmierung nerven muss, aber hier bekomme ich nunmal die _beste_ hilfe :)

Ich nimm jetzt mal ein Beispiel.

Wenn ich an die Programmierung von früher denke (DOS - BASIC) habe ich wenn ich ein Programmteil ständig sichtbar auf dem Bildschirm aktualisieren wie z.B eine Uhrzeit, Speicherauslastung etc. die DO - LOOP anweisung genutzt. Das sollte eigentlich einen "Leerlauf" Simulieren. Die DO - LOOP anweisung machte also ihre Schleife solange bis ein Knopf gedrückt wurde, führte irgendwas aus und Loopte´dann weiter.
Ich fand diese lösung ehrlich gesagt total blöd aber ich hatte einfach keine andere lösung zur Hand und ausserdem war die Prozessorauslastung sehr hoch obwohl garnichts geschah (nur das die LOOP Schleife 10000 mal in der Min. durchlief).

Da fand ich Visual Basic besser, man konnte schön mit einem Timer sagen wann was passieren soll und hatte alles schön im griff, auch ohne endlosschleife etc. das gleiche gillt auch für JavaScript, das kann man dort ja auch sehr gut steuern.

Aber nun meine Sorge/Frage, wie ist das mit C ? Muss ich da wenn ich z.B ständig (jede Sekunde) daten auf dem Bildschirm aktualisieren will auch solche FOR oder Endlosschleifen basteln oder gibt es da schon sowas wie einen Timer etc`.? Hat da jemand Tips bzw. erfahrung?
Danke!

lg Sven

  1. Hello,

    wenn man es genau nimmt, ist ein Prozessor (zumindest die üblichen) immer zu 100% "ausgelastet" vom Kernel des ihn gerade bespielenden OS. Dieses entscheidet dann, wieviel Gunst an welchen Prozess vergeben wird.

    Durch den Virtual-Mode / Protected Mode der Prozessoren hat man dann endlich einen Teil der "Aufsicht" hardcoded und an die Prozessoren übergeben. Leider sind die Schranken mMn noch nicht hart genug. Das eigentliche "Kernel" würde z.B, einen total eigenen und von anderen Programmen getrennten RAM benötigen. Es müsste auf Hardwareseite eine "Überblendmöglichkeit" für die Grafikoberfläche und die Bedienelemente benötigen. DAS wäre dann die nächste Generation der Rechner. Sicheres OS bei freier Wahl des jeweils aktiven programmausführernden Systems.

    Bei den 8086ern und DOS hatte man den Befehl "Terminate and stay resident".
    Wenn der richtig verwendet wurde, konnte man Programme "in den Hintergrund" auf den Timerinterrupt oder den User-Timerinterrupt 1C legen. Wenn die aber länger dauerten, als die berühmte 18tel Sekunde, dann war's vorbei mit dem System.

    Das Problem ist heute eigentlich immer noch dasselbe. Kein Prozess darf länger brauchen, all ihm maximal zugestanden wurde, sonst gerät das System in ein "Fischgrätenmuster" (Die Prozesse/deren Teile reihen sich nicht an, sondern fangen an, sich zu überlappen). Dann ist der Absturz unausweichlich.

    Harzliche Grüße vom Berg
    http://www.annerschbarrich.de

    Tom

    --
    Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
    Nur selber lernen macht schlau

    1. Hallo Tom,

      wenn man es genau nimmt, ist ein Prozessor (zumindest die üblichen) immer zu 100% "ausgelastet" vom Kernel des ihn gerade bespielenden OS.

      das stimmt so nicht ganz. Die heutigen Betriebssysteme schicken den Prozessor nämlich für einige Millisekunden in den Halt-Zustand, wenn kein Prozess bereit ist, wieder etwas zu tun (weil alle auf irgendein Ereignis warten). Diese Situation tritt sehr häufig ein, ein durchschnittlicher Desktop-PC verbringt heutzutage die meiste Zeit seines "Lebens" mit Warten. In diesem Halt-Zustand braucht die CPU nur sehr wenig Strom, was sowohl der Wärmeentwicklung als auch (bei Notebooks) der Akku-Laufzeit zugute kommt.

      Kein Prozess darf länger brauchen, all ihm maximal zugestanden wurde, sonst gerät das System in ein "Fischgrätenmuster" (Die Prozesse/deren Teile reihen sich nicht an, sondern fangen an, sich zu überlappen). Dann ist der Absturz unausweichlich.

      Das ist bei heutigen Betriebssystemen überhaupt kein Thema mehr. Jeder Prozess bekommt vom OS ein paar Millisekunden Rechenzeit zugestanden. Oft wird er seine Zeit nicht ausschöpfen, weil er schon vor Ablauf der Zeit wieder auf ein Ereignis warten muss, um weiterarbeiten zu können. Gibt er die Kontrolle *nicht* freiwillig innerhalb der zugebilligten Zeit wieder ab, wird er zwangsweise vom OS unterbrochen und der nächte arbeitsbereite Prozess kommt an die Reihe (präemptives Multitasking). Zu einem späteren Zeitpunkt setzt der unterbrochene Prozess seine Arbeit an exakt der Stelle wieder fort, wo er sie hat liegenlassen. Diese Unterbrechungen sind für das laufende Programm nicht einmal feststellbar (außer mit großem Aufwand und sehr hardwarenaher Programmierung, z.B. dem Beobachten von Hardware-Timern).

      Unter Windows 3.x und AFAIK sogar 9x war das noch nicht so. Da hat ein Prozess die Kontrolle behalten, bis er sie *freiwillig* wieder abgab. Eine Zwangsunterbrechung durch den Scheduler des OS fand nicht statt (kooperatives Multitasking). Das ist auch der Grund, warum eine Endlosschleife in *einem* Programm das gesamte System lahmlegen konnte.

      Schönen Abend noch,
       Martin

      --
      Wer schläft, sündigt nicht.
      Wer vorher sündigt, schläft besser.
      1. Hello,

        [...] Diese Unterbrechungen sind für das laufende Programm nicht einmal feststellbar (außer mit großem Aufwand und sehr hardwarenaher Programmierung, z.B. dem Beobachten von Hardware-Timern).

        Nun, das ist im protected Mode eines Intel-Kompatiblen so...
        Das Umschalten der Local Descriptor Tables benötigt aber schon einiges an Zeit. Das ist auch merklich. Zuviele Prozesse fressen dan  die verfügbare Zeit schon alleine dafür auf.

        Harzliche Grüße vom Berg
        http://www.annerschbarrich.de

        Tom

        --
        Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
        Nur selber lernen macht schlau

  2. Hi,

    Da fand ich Visual Basic besser, man konnte schön mit einem Timer sagen wann was passieren soll und hatte alles schön im griff, auch ohne endlosschleife etc. das gleiche gillt auch für JavaScript, das kann man dort ja auch sehr gut steuern.

    Aber nun meine Sorge/Frage, wie ist das mit C ? Muss ich da wenn ich z.B ständig (jede Sekunde) daten auf dem Bildschirm aktualisieren will auch solche FOR oder Endlosschleifen basteln oder gibt es da schon sowas wie einen Timer etc`.? Hat da jemand Tips bzw. erfahrung?

    Suchst Du vielleicht nach der Funktion sleep()?

    sleep(1);
    laesst das Programm beispielsweise eine Sekunde lang warten.

    mfG,
    steckl

    1. Hi,

      nein das meinte ich nicht.
      Ich meinte das mein Programm oder eine Function solange ausgeführt wird und wiederholt wird bis z.B eine Taste gedrückt wird oder wie auch immer ohne eine For oder Loop anweisung, z.B wie ein Timer dem ich sagen kann das er alle 0,5 sek. eine funtion starten soll....
      Ich hoffe jemand weiß was ich meine :)

      1. Hallo.

        Ich meinte das mein Programm oder eine Function solange ausgeführt wird und wiederholt wird bis z.B eine Taste gedrückt wird oder wie auch immer ohne eine For oder Loop anweisung, z.B wie ein Timer dem ich sagen kann das er alle 0,5 sek. eine funtion starten soll....

        Das hängt vom eingesetzen 'Framework' (den eingesetzen Bibliotheken) ab. Meist gibt es eine Event-Queue, in der die empfangenen Ereignisse abgelegt werden und die das Programm dann in einer Schleife abarbeitet - z.B. in SDL:

          
        for(SDL_Event event; SDL_WaitEvent(&event); )  
        {  
         switch (event.type)  
         {  
          case SDL_MOUSEBUTTONDOWN:  
           // mach zeugs  
           break;  
          
          case SDL_MOUSEMOTION:  
           // mach mehr zeugs...  
           break;  
          
          case SDL_QUIT:  
           exit(0);  
           break;  
         }  
        }  
        
        

        Timer können dann entweder ein Ereignis in die Queue einfügen, oder direkt eine 'Callback'-Funktion ausführen - siehe z.B. bei SDL oder der Windows API.

        Gruß
         Christoph

      2. Hallo,
        hast du eine Windows-Anwendung mit Nachrichtenschleife? Dann kannst du SetTimer verwenden und die WM_TIMER-Nachricht auswerten, genau dies macht der VB-Timer.
        Wenn du eine Konsolenanwensung hast, solltest du einen neuen Thread starten und darin mit Sleep warten. Das Warten mit Sleep und anderen Kernelfunktionen wie WaitForSingleObject oder auch Userfunktionen wie GetMessage ist sehr ressourcenschonend. Das spielt auf heutigen Notebooks beispielsweise eine große Rolle: Wenn man in einer Schleife wartet, geht die Prozessorauslastung auf 100% und der Lüfter fährt hoch. Das ist ein Zeichen von schlecher Programmierung.
        Es stimmt übrigens nicht, dass der Prozessor immer zu 100% ausgelastet ist. Moderne Betriebssysteme haben einen [http://en.wikipedia.org/wiki/Idle_task|Leerlaufprozess], der den Prozessor fast die ganze Zeit anhält, um Energie zu sparen.