zeitgesteuerte Endlosschleife mit Tastendruck als Abbruchkriterium realisieren?



  • Hallo!

    - Programmiersprache: C
    - reines Konsolenprogramm

    Ich möchte folgende Funktionalität realisieren:
    Der Benutzer übergibt als Parameter eine Zeitspanne.
    Das Programm liest Daten per USB von einem Logger (ist realisiert).
    Die Daten werden für die Bildschirmausgabe aufbereitet und angezeigt (ist realisiert).
    Nach der angegebenen Zeitspanne werden die Daten vom Datenlogger erneut gelesen, aufbereitet und angezeigt - oder der Benutzer drückt irgendwann die Taste "q" zum Beenden und dass Programm terminiert.

    Ich nutze zur Ausgabe ncurses.

    Wie kann ich die Zeitschleife UND die Abfrage der Taste "q" realisieren?

    Mein relevanter Quellcode:

    ... main(...)
    {
        signal(SIGALRM, my_sig_handler); /* damit alarm() nicht zum exit führt */
        initscr(); /* initialisieren von ncurses */
          alarm(5);  /* als Beispiel von 5sek durch den Benutzer übergeben */
          do
          {
            /* Lesen der Daten vom USB Datenlogger */
            ...
    
            /* Berechnung der Werte zum Anzeigen */
           ...
    
            bildschirmausgabe(1);
            while( (c=getch()) != 'q'); 
          }
          while(c != 'q');
    
          reset_bildschirm();
    }
    
    void my_sig_handler(int signum)
    {
      mvprintw(22,2,"Test...");
    }
    

    So wie ich es verstanden habe, wird nach 5 Sekunden (in meinem Beispiel) das Alarm"-Signal erzeugt. Wenn ich keinen eigenen Signalhandler angebe, dann terminiert das gesamte Programm nach der angegebenen Zeit. Also habe ich einen "Dummy"-Signalhandler eingesetzt (nach dem Buch "C und Linux"). Und das Programm terminiert auch nicht mehr. 🙂
    Aber die do-while Schleife wird trotzdem nicht nach der angegebenen Zeitspanne erneut durchlaufen.
    Wenn ich irgendwann eine Taste (natürlich nicht die "q"-Taste) drücke, dann erfolgt auch die Ausgabe von mvprintw(); in "signal(SIGALRM, my_sig_handler)" . Das bedeuted aber für mich, dass das Signal "Alarm" erst nach Tastendruck an meinen Signalhandler übergeben wird.

    Wo liegt mein Fehler?

    Für jeden Tipp und Hinweis dankbar
    Holger



  • Lösung ist gefunden.

    Ich habe auf alarm() komplett verzichtet und nutzte hingegen halfdelay() und Zeitdifferenz.

    time_t dauer, jetzt, beginn, diff_zeit;
    
    /* dauer wird durch Parameterübergabe gefüllt */
    
    main()
    {
    ...
    beginn=time(0);
    ...
    do
    {
      halfdelay(10);
      c=getch();
      if (dauer > 0)
      {
        jetzt=time(0);
        diff_zeit=difftime(jetzt, beginn);
      }
    }
    while( (c != 'q') && (diff_zeit < dauer ) );
    ...
    }
    

    Gruß
    Holger


Anmelden zum Antworten