Zeitverzögerung in C

Gast #1778626
Lesenswert?

Ich möchte gerne auf einem PC eine Zeitverzögerung von n Sekunden haben, 
so kriegt man es wohl hin aber dann wartet der Rechner aktiv oder? Wie 
macht man es besser?

1
#include <stdio.h>
2
#include <time.h>
3

4
#define WARTEZEIT 5 /* Wartezeit in Sekunden */
5

6
int main()
7
{
8
  time_t start_seconds;
9
  time_t current_seconds;
10

11
  start_seconds = time (NULL);
12
  current_seconds = start_seconds;
13
  printf ("Starting seconds: %d\n", (int)start_seconds);
14

15
  while( current_seconds < start_seconds + WARTEZEIT) /* busy waiting */
16
    current_seconds = time (NULL);
17
  printf("current_seconds = %d\n%d seconds elapsed", (int)current_seconds, WARTEZEIT);
18

19
  return 0;
20
}
Gast #1778873
Lesenswert?

@ Timmo H. (masterfx) && Rufus t. Firefly (rufus) (Moderator)
Das wichtigste ist wahrscheinlich, dass er, wenn ich den Beitrag oben 
jetzt richtig verstehe, würde er gern anders warten. Siehe:
Lila Pause schrieb:
> so kriegt man es wohl hin aber dann wartet der Rechner aktiv oder? Wie
> macht man es besser?
Wobei ich sagen würde, dass das da oben passt, wenn er etwas anderes 
zutun hätte. Hat er aber anscheinend nicht, darum kann er imho auch 
Sleep() nehmen.
Ansonsten bräuchte er wohl einen Software-Timer...
Gast #1779038
Lesenswert?

Okay, und wie mach ich das wenn ich n Sekunden lang auf ein bestimmtes 
Ereignis warten will, und wenn es innerhalb dieser Zeitspanne passiert: 
dann soll darauf reagiert werden, und wenn es nicht passiert soll die 
Rechenzeit eben den anderen Prozessen zugeteilt werden? Also so eine Art 
"bedingtes sleep()".
Gast #1779080
Lesenswert?

Ahso, nee ich bräuchts dann doch für Linux :)

Was gemacht werden soll:
Auf einem Display erscheint eine Anzeige. Der Benutzer soll nun 
innerhalb einer gewissen Zeitspanne, zum Beispiel innerhalb von drei 
Sekunden, auf diese Anzeige reagieren. Dafür drückt er auf eine Taste. 
Wenn der Tastendruck innerhalb von drei Sekunden erfolgte, gilt das als 
erfolgreiche Bestätigung, wenn nicht zählt es als ein Timeout und wäre 
sozusagen der Fehlerfall.
Hm, vielleicht kann man es doch mit busy-waiting machen, aber ist doch 
recht inelegant oder? Vielleicht einen phtread erzeugen, der auf den 
Tastendruck wartet? Bin mir grad nicht 100% sicher ob pthreads auf der 
Zielplattform verfügbar sind, d.h. vielleicht müsste ich die Bibliothek 
dafür extra hinzulinken wenn sie noch nicht da ist und möglicherweise 
ist das nicht erlaubt, weiß gerade nicht wieviel Platz auf dem 
Zielsystem man dafür bräuchte.
#1779107
Lesenswert?

Lila Pause schrieb:
> Auf einem Display erscheint eine Anzeige. Der Benutzer soll nun
> innerhalb einer gewissen Zeitspanne, zum Beispiel innerhalb von drei
> Sekunden, auf diese Anzeige reagieren. Dafür drückt er auf eine Taste.

Reden wir hier von dem normalen Monitor und der normalen Tastatur?

Falls ja: Welches Toolkit verwendest Du zur GUI-Programmierung?

Falls nein: Über welche Schnittstellen sind Display und Tastatur 
angebunden? Bei einer seriellen Schnittstelle wäre hier ein poll() bzw. 
ein select() das Mittel der Wahl.

Viele Grüße,
        Simon
Gast #1779320
Lesenswert?

Simon Budig schrieb:
> Reden wir hier von dem normalen Monitor und der normalen Tastatur?

Nein, der Steuerungsrechner kommuniziert über ein Bussystem mit dem 
Display und teilt diesem so die anzuzeigenden Informationen mit.

> Falls ja: Welches Toolkit verwendest Du zur GUI-Programmierung?

Auf dem Display-Rechner wird in C++ und mit Qt programmiert, nützt mir 
selbst aber nichts, ich progammiere den Steuerungsrechner und habe dort 
eben C als Programmiersprache.

> Falls nein: Über welche Schnittstellen sind Display und Tastatur
> angebunden? Bei einer seriellen Schnittstelle wäre hier ein poll() bzw.
> ein select() das Mittel der Wahl.

Im Endeffekt werden Signale über eine Art Prozessleitsystem zwischen 
beiden hin- und hergeschickt, die ich dann im Speicher (des 
Steuerungsrechners) in Form von globalen Variablen vorliegen habe.
Gast #1779367
Lesenswert?

So, hier noch eine professionelle UML-Grafik ;)

1
              +-------------+                              +-----------+
2
              |             |                              |           |
3
              | Steuerungs- |------ starte_Testlauf ------>|  Display  |------------------------+
4
              | rechner     |                              |           |                        |
5
              |             |                              |           |                        |
6
              +-------------+                              +-----------+ <---- zeige_Button ----+
7
                     |                                           |
8
                     |                                           |
9
                     |<------------ Button gedrueckt? -----------|
10
  +------------------|                                           |
11
  |                  |                                           |
12
  |                  |                                           |
13
  +-wenn Button ---->|                                           |
14
    gedrueckt und    |                                           |
15
    weniger als 3    |                                           |
16
    Sekunden ver-    |                                           |
17
    gangen: Test=OK, |                                           |
18
    else: nicht OK   |                                           |
19
                     |---------- Testergebnis anzeigen --------->|                                           |
20
                     |                                           |---------------+
21
                     |                                           |               |
22
                     |                                           |<---Anzeige----+
23
                     |                                           |
24
                     |                                           |
25
                     |     ( ------ ggf. Wiederholung ------> )  |
26
                     |              mit anderem Signal/          |
27
                     |              Button                       |
28
                     |                                           |
29
                     |                                           |
30
                     |                                           |
31
                     |                                           |
32
                     X                                           X
#1779380
Lesenswert?

Lila Pause schrieb:

> Zur Entwirrung: Ich sitze gerade an einem Rechner mit Windows und MinGW,
> laufen soll das Ganze aber später auf einem Linux Rechner.

Nicht die optimale Wahl. In aller Kürze:
MinGW für Verwendung vom Windows-API.
Cygwin für Verwendung vom Unix/Linux-API.

Wenn man also unter Windows entwickelt, aber eigentlich Linux meint, 
dann ist man mit Cygwin besser dran.
Gast #1779454
Lesenswert?

> Im Endeffekt werden Signale über eine Art Prozessleitsystem zwischen
> beiden hin- und hergeschickt, die ich dann im Speicher (des
> Steuerungsrechners) in Form von globalen Variablen vorliegen habe.

Dann schau mal ins Handbuch deines Prozessleitsystems obs da eine 
Funktion gibt, mit der du auf Ereignisse warten kannst. Oder Callbacks 
bei Ereignissen aufrufen lassen kannst.

Wenns nichts gibt, wirst du pollen müssen. Dazu nimmst du dann sleep 
oder einen anderen Timer mit möglichst hohem Wert (um die CPU möglichst 
wenig zu belasten), aber niedrig genug für die gewünschte Reaktionszeit.
#1779603
Lesenswert?

Lila Pause schrieb:
> der Steuerungsrechner kommuniziert über ein Bussystem mit dem
> Display und teilt diesem so die anzuzeigenden Informationen mit.

Ok, Du programmierst den Steuerungsrechner und der läuft letztlich mit 
Linux.

Die Information, dass der Button gedrückt wurde, kommt über ein 
"Bussystem", meine Kristallkugel sagt mir, dass der letztlich über eine 
Device-Datei in dem Linux-System repräsentiert wird, d.h. du machst 
irgendwann ein

1
bus = open ("/dev/meinbus", O_RDWR);

oder etwas vergleichbares.

Irgendwann ist der Zeitpunkt gekommen, dann müsste das etwa so aussehen:
1
#include <poll.h>
2
...
3

4
void meine_testfunktion () {
5
  struct pollfd pfd[1];
6
  unsigned char answer[40];
7
  int ret;
8

9
  ret = write (bus, "starte Testlauf\n", 16);  
10
  if (ret < 0)
11
    ;/* Fehlerbehandlung */
12

13
  /* daraufhin stellt das Display-System den Button dar */
14

15
  pfd[0].fd = bus;
16
  pfd[0].events = POLLIN;
17

18
  ret = poll (pfd, 1, 3000);
19
  /* warte max. 3s auf Daten zum Lesen bei dem "bus" Filedeskriptor */
20

21
  if (ret < 0)
22
    ;/* Fehlerbehandlung */
23

24
  if (ret == 0)
25
    ;/* Timeout ist aufgetreten, kein Buttondruck */
26

27
  if (ret > 0)
28
    {
29

30
      if (pfd[0].revents & POLLIN)
31
        {
32
          ret = read (bus, answer, 40);
33
          if (ret < 0)
34
            ;/* Fehlerbehandlung */
35

36
          if (strncmp (answer, "button wurde gedrueckt.\n", 24))
37
            ; /* behandle Buttondruck */
38
        }
39
    }
40
}

So in etwa (von der Struktur her). Natürlich ist dieser Code nur mal 
eben aus dem Kopf hingehackt und kein Stück getestet, Du solltest auf 
jeden Fall selber nachlesen, was die einzelnen Teile machen und sie auf 
deine Bedürfnisse anpassen - es ist ja eher unwahrscheinlich, dass über 
den Bus derartige Klartextmeldungen kommen  :)

Zentral für das Warten auf Input ist der poll() Systemaufruf. 
Busy-Waiting - wie du es vorschlägst - ist eine ganz schlechte Idee. Bei 
poll() wird der wartende Prozess echt schlafengelegt und aufgeweckt, 
sobald Input zum Lesen zur Verfügung steht.

Ich hoffe das hilft,
        Simon
#1779610
Lesenswert?

sebastians schrieb:
> Wenns nichts gibt, wirst du pollen müssen. Dazu nimmst du dann sleep
> oder einen anderen Timer mit möglichst hohem Wert

Wenn das unter Linux läuft, dann macht man das nicht, sondern nimmt - 
wie in dem letzten Posting von mir skizziert - poll() oder select(), 
wobei ich poll() bequemer finde.

Damit kann man eine maximale Wartezeit vorgeben, wird aber sofort 
aufgeweckt, falls Daten auf einem der beobachteten Filedeskriptoren 
anliegen (man kann poll ein Array von struct pollfd's geben, dann 
überwacht der mehrere).

(das "if (strncmp...)" sollte natürlich eigentlich "if (!strncmp...)" 
heißen)

Viele Grüße,
        Simon
Gast #1779844
Lesenswert?

Simon, vielen Dank für die Tipps, nur mit den /dev "Dateien" und 
Filedeskriptoren kann ich da nicht ran. Das Empfangsmodul für den 
Feldbus (MVB) stellt die Signale, die für die Verarbeitung benötigt 
werden, wie gesagt in Form von globalen Variablen im Speicher zur 
Verfügung. Mit diesen kann/darf/soll/muss ich operieren. Ich kann 
höchstens neue Signale definieren die dann zusätzlich in die bisher 
schon vorhandenen Telegramme eingefügt werden, aber der Datenfluss ist 
so vorgegeben und wenn ich da selbst nochmal dran rumpfusche, haut mir 
mein Chef auf die Finger ;)
#1779856
Lesenswert?

Lila Pause schrieb:
> Das Empfangsmodul für den
> Feldbus (MVB) stellt die Signale, die für die Verarbeitung benötigt
> werden, wie gesagt in Form von globalen Variablen im Speicher zur
> Verfügung.

OK, dann musst Du das API dieses Empfangsmoduls (das ist Software, 
richtig?) absuchen und nach Synchronisationsmechanismen suchen. Falls 
Dir nur Busy-Waiting bleiben sollte, dann ist das API schlecht und 
sollte überdacht werden.

Läuft das Empfangsmodul als separater Thread? Oder als eigener Prozess 
der über shared Memory mit deinem Programm kommuniziert?

Viele Grüße,
        Simon

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren