Verwendung von clock_t clock()
-
ujt schrieb:
Da habe ich wohl irgenwo einen Denkfehler.
Die Hilfe von VC2008 gibt an, dass clock_t als long = 4 Bytes definiert ist. Also gibt es nach 2.147.483.637 Ticks, das wären nach meinen Überlegungen und CLOCKS_PER_SEC=1000 rd. 24 Tagen, einen Überlauf.Ok, dann ist dein System eben eines mit einem sehr kleinen clock_t. Ist das wirklich relevant? Was genau hast du vor, dass dies eine Rolle spielen könnte? Hat man in Windows eigentlich mittlerweile den Bug gefixt, dass das Betriebssystem nach dieser Zeit aus genau diesem Grund abstürzt?
Wenn du uns sagst, was du erreichen möchtest, anstatt wie du es erreichen möchtest (oder hier: Wie du es nicht erreichen möchtest), dann könnte man dir übrigens viel besser helfen.
-
time(&start); fehler=0; while( !Daten_im_seriellen_Puffer() ) { time(&messen); if(difftime(messen, start)) {fehler=1; break;} }
Ich warte auf Antwort vom seriellen Port. Damit ich nicht ewig warte wenn das
Gerät nicht antwortet habe ich die difftime-Funktion eingebaut. Nur ist eine
Sekunde etwas zu lange gewartet. In einem Zyklus frage ich 60 Geräte ab und
da kann sich die Zeit tüchtig summieren.
-
Das spielt bei dir keine Rolle, da dank Zweierkomplement auch die unsigned-Differenzen passen.
Wenn dir dabei unwohl ist, kannst du ja vergleichen, ob die neue Zeit kleiner als die alte Zeit ist und dann extra behandekn.SeppJ schrieb:
Hat man in Windows eigentlich mittlerweile den Bug gefixt, dass das Betriebssystem nach dieser Zeit aus genau diesem Grund abstürzt?
Ich habe noch Windows 95 und Windows 98 Systeme, die monatelang durchlaufen.
Bei den Programmen die darauf laufen, werden auch Zeitdifferenzen mit clock() ermittelt. Das gibt keine Probleme.
-
[quote="DirkB"]
Wenn dir dabei unwohl ist, kannst du ja vergleichen, ob die neue Zeit kleiner als die alte Zeit ist und dann extra behandekn.
[/quote]Gehst du davon aus oder weißt du, dass clock() nach Überlauf wieder bei 0 anfängt?
-
ujt schrieb:
Gehst du davon aus oder weißt du, dass clock() nach Überlauf wieder bei 0 anfängt?
Nicht bei 0, aber clock_t ist (bei dir) ein signed Typ. Dies ist zwar, wie schon erwähnt, bei Überlaufen ganz streng gesehen undefiniert, aber wenn du ein System hast, auf dem Windows läuft, dann kannst du mit Sicherheit davon ausgehen, wie DirkB schon gesagt hat, dass im Zweierkomplement gerechnet wird. Das heißt, der maximale Wert + 1 ist der minimale Wert und minimaler Wert - maximaler Wert ist wie erwartet auch 1.
-
Wenn clock_t ein unsigned Integer ist, ist das sogar so im Standard definiert.
Wenn es ein signed Integer ist, ist es zumindest unter Windows so, das ein int von INT_MAX auf INT_MIN überläuft. Der Wert wird also negativ.
Wenn du jetzt aber (im Wertebereich von int) rechnestINT_MIN - INT_MAX
ergibt das 1.
Das gleich gilt dann für long.clock_t darf allerdings auch ein Fließkommatyp sein.
In den Compilern für Windows, die ich gerade gefunden habe (VS2005, VS2008 und gcc) ist es vom Typ long.
Ein Compiler für HP-UX hat es als unsigned long definiert.Die Differenz
neueZeit-alteZeit
gibt da eigentlich immer den richtigen Wert. (Es sei denn, die Differenz ist zu groß)
-
#include <stdio.h> #include <limits.h> int main() { int i = INT_MIN - INT_MAX; unsigned int ui = 0U - UINT_MAX; printf("%d - %d = %d\n", INT_MIN, INT_MAX, i); printf("%u - %u = %u\n", 0U, UINT_MAX, ui); return 0; }
ergibt:
-2147483648 - 2147483647 = 1 0 - 4294967295 = 1
Guckst du: http://codepad.org/ABvlmxKr
-
SeppJ schrieb:
Dies ist zwar, wie schon erwähnt, bei Überlaufen ganz streng gesehen undefiniert, aber wenn du ein System hast, auf dem Windows läuft, dann kannst du mit Sicherheit davon ausgehen, wie DirkB schon gesagt hat, dass im Zweierkomplement gerechnet wird. Das heißt, der maximale Wert + 1 ist der minimale Wert und minimaler Wert - maximaler Wert ist wie erwartet auch 1.
Problem ist halt, dass einige Compiler die Undefiniertheit des Signed-Overflows recht aggressiv ausnutzen, GCC und Clang gehören z.B. dazu. Da bringt es einem nichts, wenn die Berechnung auf Maschinenebene wohldefiniert ist, wenn die passenden Instruktionen nie generiert werden.
-
Fischrahmsoße schrieb:
SeppJ schrieb:
Dies ist zwar, wie schon erwähnt, bei Überlaufen ganz streng gesehen undefiniert, aber wenn du ein System hast, auf dem Windows läuft, dann kannst du mit Sicherheit davon ausgehen, wie DirkB schon gesagt hat, dass im Zweierkomplement gerechnet wird. Das heißt, der maximale Wert + 1 ist der minimale Wert und minimaler Wert - maximaler Wert ist wie erwartet auch 1.
Problem ist halt, dass einige Compiler die Undefiniertheit des Signed-Overflows recht aggressiv ausnutzen, GCC und Clang gehören z.B. dazu. Da bringt es einem nichts, wenn die Berechnung auf Maschinenebene wohldefiniert ist, wenn die passenden Instruktionen nie generiert werden.
Nicht so aggressiv, dass es hier relevant werden könnte. Dazu müsste zur Compilezeit feststehen, dass ein Überlauf erfolgt. Um zur Laufzeit Überlaufe abzufangen müsste sogar zusätzlicher Code erzeugt werden, dass wird garantiert nicht passieren. GCC und CLang benutzen sowieso einen 64 Bit Typ für
clock_t
(zumindest auf 64-Bit Maschinen), womit wir wieder bei ein paar Millionen Jahren sind.edit: Die eigentliche Frage ist jedoch, ob
clock
hier überhaupt das richtige Mittel ist. So wie das klingt, möchte der TE doch eher Unterschiede in der Echtzeit wissen, also ein klassischestime
oder das entsprechende Äquivalent aus C++11.
-
ujt schrieb:
Die Hilfe von VC2008 gibt an, dass clock_t als long = 4 Bytes definiert ist. Also gibt es nach 2.147.483.637 Ticks, das wären nach meinen Überlegungen und CLOCKS_PER_SEC=1000 rd. 24 Tagen, einen Überlauf.
Daraus schließe ich, dass du Windows als Plattform verwenden willst. Wenn du Plattformspezifik ausnutzen willst, helfen Standardfunktionen wie clock() wenig, probiere mal WinAPI:: GetTickCount64()
Die Auflösung ist mit ca. 15ms annehmbar, der Überlauf sollte erst bei vielen Jahren Sessionlaufzeit auftreten.
-
*snip*
-
Vielen Dank für Eure Hilfe. Meine Lösung sieht jetzt so aus:
start=clock(); fehler=0; while( !Zeichen_im_seriellen_Puffer ) { messen=clock(); if(messen < start) { start=clock(); continue; } if( (messen-start) > 100) {fehler=1; break;} }
Einziger Wermutstropfen ist, dass beim Übergang von positiven zu
negativen Zahlen die Schleife max. 0,2s durchlaufen wird. Aber da
das ja nur einmal in 48 Tagen passiert kann ich das verschmerzen.PS: Warum erscheint mein Quoting und mein Code nicht in so tollen
Kästchen wie bei Euch?
-
ujt schrieb:
PS: Warum erscheint mein Quoting und mein Code nicht in so tollen
Kästchen wie bei Euch?Hast du BBCode ausgeschaltet? Guck mal unter dem Editierfenster, unter den Smileys, unter den Formatierungsbuttons, unter den griechischen Buchstaben, da sollten Optionen für den Beitrag stehen, da gibt es eine "BBCode in diesem Beitrag deaktivieren".
-
SeppJ schrieb:
Hast du BBCode ausgeschaltet? Guck mal unter dem Editierfenster, unter den Smileys, unter den Formatierungsbuttons, unter den griechischen Buchstaben, da sollten Optionen für den Beitrag stehen, da gibt es eine "BBCode in diesem Beitrag deaktivieren".
Melde Vollzug! Häkchen entfernt! Danke