Wie stellen Sie eine genaue countdown-timer mit clock_gettime?
Könnte jemand bitte erklären, wie man einen countdown-timer mit clock_gettime, unter Linux. Ich weiß, Sie können verwenden Sie die clock () - Funktion, um die cpu-Zeit, und multiplizieren Sie es durch CLOCKS_PER_SEC um die tatsächliche Zeit, aber ich habe gehört, dass die clock () - Funktion ist nicht gut für diese geeignet.
So weit ich habe versucht diese (eine Milliarde ist die pause für eine Sekunde)
#include <stdio.h>
#include <time.h>
#define BILLION 1000000000
int main()
{
struct timespec rawtime;
clock_gettime(CLOCK_MONOTONIC_RAW, &rawtime);
unsigned long int current = ( rawtime.tv_sec + rawtime.tv_nsec );
unsigned long int end = (( rawtime.tv_sec + rawtime.tv_nsec ) + BILLION );
while ( current < end )
{
clock_gettime(CLOCK_MONOTONIC_RAW, &rawtime);
current = ( rawtime.tv_sec + rawtime.tv_nsec );
}
return 0;
}
Ich weiß, das wäre nicht sehr nützlich, auf Ihre eigene, aber sobald ich herausgefunden habe, wie man Zeit richtig kann ich dieses in meine Projekte. Ich weiß, dass sleep() kann für diesen Zweck verwendet werden, aber ich möchte code der timer selbst damit kann ich mich besser integrieren es in meinem Projekte - wie beispielsweise die Möglichkeit der Rückkehr der Zeit, im Gegensatz zu pausieren, das ganze Programm.
- Und ja, ich gelinkt habe es mit -lrt
- Willkommen zum Programmierer. Bitte nehmen Sie sich einen Augenblick Zeit und Lesen Sie die Website FAQ wo Sie finden einige gute Informationen über die Fragen hier. Diese Frage ist wahrscheinlich besser gedient, SO wie es befasst sich mit der code-Implementierung. Bitte nicht wieder Fragen, es gibt, wie diese migriert werden können. Eine Allgemeine Regel ist, wenn Ihre Frage hat Sie vor Ihrer IDE es gehört SO. Wenn es Sie hat, vor einem whiteboard gehört es auf die Programmierer.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Bitte, tun Sie das nicht. Du bist burning CPU-Leistung für nichts in einem busy-loop.
Warum nicht die
nanosleep()
- Funktion statt? Es ist perfekt geeignet, um die use-case-Sie skizziert. Oder, wenn Sie möchten, eine einfachere Schnittstelle, vielleicht so etwas wieDer Unterschied ist, dass mit dieser CPU frei ist, etwas anderes zu tun, als vielmehr drehen sich wie ein verrückter Eichhörnchen auf speed.
volatile sig_atomic_t
variable. Erstellen Sie einen timer mittimer_create()
(siehe kernel.org/doc/man-pages/online/pages/man2/timer_create.2.html), dann Bewaffnen Sie,/Entwaffnen Sie, bei Bedarf, mittimer_settime()
(siehe kernel.org/doc/man-pages/online/pages/man2/timer_settime.2.html). Die Lieferung des Signals, um das signal-handler interrupt-Sperrung I/O-Funktionen, so müssen Sie behandeln-1
miterrno == EINTR
von der Sperrung-Funktionen. Ich mag, um die interrupt-Wiederholung bald nach dem trigger, also glaube ich nicht, miss Veranstaltungen.Dies ist keine Antwort, sondern ein Beispiel, wie Signale und eine POSIX-timer zu implementieren, die einen timeout-timer; soll eine Antwort auf die OP ' s Nachfolge-Frage in einem Kommentar auf die akzeptierte Antwort.
Wenn Sie speichern, wie Sie oben
timer.c
, können Sie es kompilieren, das beispielsweise mitund führen Sie es mit
./timer
.Wenn Sie Lesen Sie den code oben sorgfältig, Sie werden sehen, dass es tatsächlich eine periodische timer-Signals (in Millisekunden-Intervallen), mit einer Variablen Verzögerung, bevor das erste signal. Das ist nur eine Technik, die ich mag zu verwenden, um sicherzustellen, dass ich don ' T verpassen das signal. (Das signal wird wiederholt, bis der timeout nicht gesetzt ist.)
Beachten Sie, dass obwohl Sie tun können, Berechnung in ein signal-handler sollten nur Funktionen verwenden, die sind async-signal-safe; siehe man 7 signal. Auch, nur die
sig_atomic_t
Typ atomic-wrt. normale single-threaded-code und einen signal-handler. Also, es ist besser, benutzen Sie einfach das signal als Indikator, und die eigentliche code in ein eigenes Programm.Wenn man wollte-z.B. update-monster-Koordinaten in ein signal-handler ist es möglich, aber ein bisschen tricky. Ich würde drei arrays, die die monster-Informationen, und verwenden Sie GCC
__sync_bool_compare_and_swap()
zur Aktualisierung der array-Zeiger-sehr viel die gleiche Technik, triple-buffering in der Grafik.Wenn Sie mehr als eine gleichzeitige timeout, Sie könnte verwenden Sie mehrere Timer (es gibt eine Reihe davon), aber die beste option ist, um zu definieren, timeout-slots. (Man kann die generation von Zählern zu erkennen "vergessen" timeouts, und so weiter.) Wenn Sie eine neue timeout-Wert gesetzt ist oder nicht gesetzt aktualisieren Sie den timeout zu reflektieren, die nächste timeout abläuft. Es ist ein bisschen mehr code, aber wirklich eine einfache Erweiterung des oben.