clock() nutzen, muss aber länger als ein Jahr laufen können.



  • So, hat schon mal jemand das Problem?

    wenn ich mir die Rückgabe von clock() aus time.h anschaue, ist es entweder eine unsigned long, oder sogar nur eine normale long.

    wenn ich jetzt anfange zu rechnen, dann ist bei ca. 49 Tagen bei Unsigned, oder bei 25 Tagen ein Sprung von max auf min.

    Ich muss jetzt aber jeder Zeit, einen Timeout kontrolieren können, der in long vorliegt. Nehmen wir mal an, das der Timeout nach max erst zum tragen kommt. Dann komme ich mit dem vergleich if (clock()-incomingTime-timeout>=0) kein Staat mehr zu machen. In dem Moment würden alle Timeouts di vor dem umbruch reinkommen, abgebrochen werden.

    Hat jemand ein Template, eine Funktion, oder eine Idee, wie es mit wenig Auffand zu Regeln ist? 😕



  • Verwende doch time() zur Zeitmessung (ist zwar nur auf Sekunden genau, aber dafür dauert es auch etwas länger, bis das überlaufen wird - und wer Zeitspannen über ein Jahr betrachtet, dürfte mit ein paar Millisekunden kein Problem haben, oder?).



  • Doch habe ich, ist einen Anwendung für USB, und ich brauche alles in Millisekunden. Und den timeout in long, kann ich nicht ändern.



  • Dann komme ich mit dem vergleich if (clock()-incomingTime-timeout>=0) kein Staat mehr zu machen.

    du meintest sicherlich if ((int)(clock()-incomingTime-timeout)>=0).
    ich kann dem text nicht genau entnehmen, was das problem ist.
    a) das programm soll endlos lange laufen können. dabei werden auch zukünftige ereignisse geplant, die mehr als 50 tage in der zukunft liegen, und sozusagen timer aufgezogen, die dann in mehr als 50 tagen ein event auslösen sollen.
    b) das programm soll endlos lange laufen können. dabei werden auch zukünftige ereignisse geplant, die nie mehr als 25 tage in der zukunft liegen.

    für b) ist die sache ganz einfach gelöst. zeitpunkt a gilt als größer als zeitpunkt b, wenn int(a-b)>0. der zeipunkt um 1000 clocks nach jetzt ist jetzt+1000. überlauf wird einfach ignoriert. klappt schon. kein problem, in 40 tagen nen timer aufzuziehen, der erst in weiteren 20 tagen feuert.
    für a) ist die sache dann einfach, wenn du sowas wie eine hauptschleife hast, die nen 64-bittigen-rundenzähler hat (die poll-abfrage des event-heaps ist perfekt geeignet). der 64-bitter muß nur mit clock() synchronisiert werden. der 64-bitter macht natürlich auch alle tricks von "für b", damit du die programmlaufzeit nicht künstlich auf 500 millionen jahre beschränkst, sondern nur fordern mußt, daß keine keine timer über mehr als 250 millionen jahre aufgezogen werden.

    außerdem kannste dich in die abgründe des frickelns begeben und die events mit nem tageszähler ausstatten und sie unter zählererniedrigung tageweise hoppeln lassen, bis sie ankommen. dann mußt du aber in den kommentar schreiben, daß ich dir nicht geraten habe, das so zu machen.



  • b ist die Perfekte Lösung für mein Problem 🙂 ein timer der 250 millionen Jahre läuft.
    Danke.



  • folgendes Problem tauch auf:

    timer_64=timer_64+this_time+(4294967295l-last_time);

    Fehlermeldung:

    16 \usbtime.c [Warning] this decimal constant is unsigned only in ISO C90

    kann man was dagegen machen? Muss man was dagegen machen?



  • Versuch's mal mit "4294967295ul"



  • funzt 🙂 dankte



  • Nightstorm schrieb:

    timer_64=timer_64+this_time+(4294967295l-last_time);

    macht das das gleiche wie

    timer_64=timer_64+this_time-1-last_time;
    

    ?
    ich frage mich außerdem, wozu da -1 steht. wäre -0 nicht genug? oder 0 statt 4294967295l?
    falls das die synchronisierstelle ist, wäre die nicht natürlich als

    clock_t last_time=this_time;
    this_time=clock();
    clock_t step=this_time-last_time;//muss kleiner als 25 tage sein
    timer_64=timer_64+step;
    

    ?
    das würde sich jedenfalls herauslesen lassen, wenn ich mal statt

    timer_64=timer_64+this_time+(4294967295l-last_time);
    

    ein

    timer_64=timer_64+this_time+(0-last_time);
    

    schreibe und gleich draus

    timer_64=timer_64+this_time-last_time;
    

    mache.
    ich mag bei sowas aber schmuckklammern

    timer_64=timer_64+(this_time-last_time);
    

    oder

    timer_64+=this_time-last_time;
    

    außerdem macht unter der annahme, daß du diese zeile in code hast, der so aussieht, wie meiner, dein -1 jedesmal ein problem, wenn du zufällig mehr als 1000-mal pro sekunde drüberläufst. da könnte die zeit rückwärts laufen. und wenn nicht, würde doch die auslastung des rechners beeinflussen, wie oft er dazu kommt, die zeit um 1ms zurückzustellen.



  • danke Volkard, ich habe mich auch nochmal mit der Berechnung von last_time-clock(); auseinander gesetzt, und festgestellt, das immer die exakten Werte heraus kommen. Also max last_time_max-this_time ist this_time. Habe ich bis ich mir Binäres Subtrahieren angeschaut habe keinen Sinn für mich gemacht, aber un ter der Berücksichtigung von Binärer Subtraktion, scheint es zu funktionieren.

    Kein Timeout bei USB sollte länger als eine Minute sein. Deshalb hat sich der endlos Zähler erledigt.

    Gruß Peer



  • Nightstorm schrieb:

    Kein Timeout bei USB sollte länger als eine Minute sein. Deshalb hat sich der endlos Zähler erledigt.

    deswegen würde ich einen endloszähler mit 32 bit nehmen und keinen 64-bitter.
    also

    timeToWakeUp=clock()+myDelay;
    

    und dann statt

    if(clock()<=timeToWakeup)... //geht alle 49,7 tage für eine sekunde lang nicht. fröhliche fehlersuche!
    

    lieber

    if((int32_t)clock()-(int32_t)timeToWakeup)>=0)... //geht immer, ist überlauffest.
    

    ich stelle mir mal vor, ein clock_t kann nur zahlen von 0 bis 999.
    983-973 = 10
    993-983 = 10
    003-993 = 10 //wichtig!
    013-003 = 10
    023-013 = 10
    013-023 = 990 //uih
    die 990 sollte ich besser als -10 interpretierten, also daß die erste zahl kleiner als die zweite ist.
    das mache ich einfach, indem ich die 990 in einen signed typ caste. genauer: ich caste schon die zahlen vor dem subtrahieren. kostet ja nix, aber ich erlebe keine überraschungen, falls auf dieser maschine der clock_t ein unerwarteter typ ist.
    vielleicht noch genau dafür ne funktion schreiben

    inline bool timeReached(clock_t timeToWakeup){
       if((int32_t)clock()-(int32_t)timeToWakeup)>=0)
          return true;
       else
          return false;
    }
    

    und dann immer die nehmen. oder ein makro. irgendwas riecht hier nach embedded systems und schwachem compiler.



  • Weder noch, sondern Linux-Libary nach Windows-Libary Portierung, bei identischer API 🙂


Anmelden zum Antworten