Für dieses Forum muß Javascript im Browser aktiviert werden!
Kommentar: Einfügen von HTML im Kommentar: Link einfügen: <a href="LINKURL" target="_blank">LINKTITEL</a> Bild einfügen: <img src="BILDURL"> Text formatieren: <b>fetter Text</b> <i>kursiver Text</i> <u>unterstrichener Text</u> Kombinationen sind auch möglich z.B.: <b><i>fetter & kursiver Text</i></b> C2 Quellcode formatieren: <code>Quellcode</code> ASM Quellcode formatieren: <asm>Quellcode</asm> (Innerhalb eines Quellcodeabschnitts ist kein html möglich.) Wichtig: Bitte mache Zeilenumbrüche, bevor Du am rechten Rand des Eingabefeldes ankommst ! > Hallo Mark, > > Ich vermute, daß Du einen Fehler in Deinem Programm hast, welcher beim > geposteten Code nicht enhalten ist. > > Denn wait funktioniert eindeutig. > Sogar die beiden Threads funktionieren. > Gewöhne Dir aber bitte eine andere Klammersetzung an. > Ich weiß, daß es in C üblich ist, die geschweiften Klammern noch in der Zeile > des "einleitenden" Befehls zu setzen und gern auf richtiges Einrücken zu verzichten. > Aber spätestens, wenn man einen Fehler suchen muß, behindert das einen sehr. > Daher rücke lieber so ein: > <code> > long timer; > int x,y; > > thread regeln > { > loop > { > timer=system.timer(); > y=y+1; > wait timer+10000<=system.timer(); > } > } > > thread main > { > run regeln; > x=x+1; > } > </code> > Bei kurzen Routinen fällt es zwar noch nicht stark auf, aber bei längeren > kann es aber sonst schnell unübersichtlich werden. > > Nun aber zum wait zurück: > Prinzipiell kann man hier wait verwenden. Jedoch ist ein sleep eindeutig weniger belastend! > Ich weiß nicht, wie Du auf die Idee kommst, ein sleep würde andere Threads > in Mitleidenschaft ziehen? > Ein sleep ist eine einzge VM-Instruktion. Dazu noch ein Parameter der einmal > auf den Stack geschoben wird. > Um die Funktionsweise des sleep einmal zu erläutern: > Gelngt der Programmablauf zu einem sleep, so wird zuerst der Wert(Konstante oder > Inhalt einer Variable) auf den Stack geschoben, und dann VM_SLEEP ausgeführt. > VM_SLEEP ist zweigeteilt. Es wird daher geprüft, ob sich der Thread bereits in > einer "Sleep-Phase" befindet. > > Ist das nicht der Fall, werden ein Active-Flag undzwei interne Threadvariablen mit > dem Startzeitpunkt(Timer) des Sleeps, sowie des Endzeitpunkts beschrieben. > Anschließend wird der Threadpointer um 1 verringert, damit sich VM_SLEEP erneut durchlaufen > wird, sobald der Thread wieder "Rechenzeit" bekommt. > Jetzt wird noch die Rechenzeit abgegeben. > > Erhält nun der Thread wieder Rechenzeit, so wird das Active-Flag des Sleeps abgefragt. > Da dieses nun auf True steht, erfolgt nun eine weitere Abfrage, die prüft, ob bereits > die Wartezeit abgelaufen ist. > Ist diese nicht abgelaufen, wird der Threadpointer wieder um eins verringert und > die Rechenzeit abgegeben. > Ist die Wartezeit abgelaufen, wird das Flag gelöscht, und der Thread wird > nach dem sleep fortgesetzt. > > Im Ganzen nimmt VM_SLEEP bei jedem Durchlauf nur eine VM-Instruktion in Anspruch. > > Wenn statt dem sleep nun eine Konstruktion mit wait gemacht wird, > belastet dies die CC2 mehr. Es steht dann weniger "Rechnzeit für andere Threads zur Verfügung. > Denn ein wait besteht mehr als aus einer VM_Instruktion. > Genaugenommen entspricht das etwa dieser Schleife: > <code>loop > { > if <Bedingung> break; > yield; > }</code> > Eine einfache Schleife besteht aus einer VM_Instruktion. > Dazu kommt noch das if und der Sprung und aus der Schleife: zwei Instruktionen > Und das yield mit einer Instruktion. > Die Bedingung selbst besteht natürlich auch aus einer Anzahl an Instruktionen. > Das <code>timer+10000<=system.timer()</code> in Deinem Fall sind 5 Instruktionen. > Somit ergibt sich bei Deinem wait eine Anzahl von 9 Instruktionen. > Von diesen 9 Instruktionen werden, solange die Bedingung nicht erfüllt ist, immer 8 durchlaufen. > Ist die Bedingung erfüllt, sind es ab Schleifenbeginn "nurnoch" 7 Instruktionen. > (Die IDE erzeugt aus wait eine kleine Schleife, da wait keine eigene VM_Instruktion ist.) > > Dagegen stehen die bei sleep anfänglich zwei Instruktionen, und während > des "Wartens" eine Instruktion. > Somit ist ein sleep immer ressourcenschonender als ein vergleichbares Konstrukt mir wait. > > Übrigens sollte man, um mit dem Timer eine Wartezeit zu berechnen, auf dieses Konstrukt verzichten: > <code>timer+10000<=system.timer()</code> > Es hat den Nachteil, daß bei einem Überlauf der Vergleich durch die negativen Werte > eine Zeit lang ein gegenteiliges Ergebnis liefert. (Hier: gut 10s lang) > Besser ist es, dies so zu berechnen: > <code>system.timer()-timer<=10000</code> > Hier wird die Differenz gebildet. Zu beachten ist aber, daß immer vom "höheren" Wert > der "kleinere" abgezogen wird.(Oder anders ausgedrückt: Vom aktuelleren (Timer-)Wert muß > immer der alte Wert abgezogen werden.) > Nur so ist die Differenz immer positiv. > Außer natürlich, wenn über dreieinhalb Wochen vergehen. Denn solange dauert es, > bis der Timer seine über 2,1Mrd. erreicht, wo er schließlich überläuft. > Aber Zeitdifferenzen von mehreren Wochen erfasst man sicher nicht mit dem ms-Timer. ;-) > Probleme mit einer falschen Berechnung treten daher erst nach ca. 3,5 Wochen auf, > und wiederholen sich dann etwa alle 7 Wochen. (solange dauert es, bis der Timer einmal rum ist.) > > Daher nochmal zur Wiederholung: > Man rechnet immer "Zeit_neu Minus Zeit_alt = Differenz". > > Aber um nochmal zu Deinem direkten Problem zu kommen: > Ich vermute, daß in Deinem restlichen Programm irgendwo Fehler sind. > In diesem Fall würde ich sagen, daß Du irgendwo außerhalb definierter > Arraygrenzen auf Variablen zugreifst, und somit auch Deine timer-Variable erwischt. > Nimm einmal Deine Schleife, wie sie ist, ersetze das wait dennoch durch ein sleep, > und überwache aus einem <u>anderen</u> Thread die timer-Variable. > Wenn diese sich öfters als alle etwa 10sek. (<code>sleep 10000;</code>) ändert, > dann ist mein Verdacht bestätigt. Dann heißt es das Programm nach solchen > Überschreitungen zu durchsuchen. > Das naheliegenste sind Variabeln, die unmitelbar vor <code>long timer;</code> definiert sind. > Führe daher bitte mal alle globalen Variablen des Moduls in der korrekten Reihenfolge auf. > Wenn in diesem Modul keine weiteren globalen Variablen definiert sind, > dann die des vorherigen Moduls. > > MfG André H. > > > > Hallo! > > Ich verzweifle grade an simpelsten Abläufen! Folgenden Code habe ich: > > <code> > > long timer; > > > > thread regeln > > { > > loop{ > > timer=system.timer(); > > do something....; > > > > wait timer+10000<=system.timer(); > > } > > } > > > > main { > > run regeln; > > do something else...; > > } > > </code> > > Aus dem Main-Thread soll also einfach nur der Thread "Regeln" aufgerufen werden, in dem > > dann eine Schleife abläuft und alle 10 Sekunden etwas tun soll. Das Problem dabei ist, dass sie > > nicht 10 Sekunden wartet, sondern direkt weiter macht. Ich habe auch schon ausprobiert, das Ganze > > ohne die Schleife zu machen, aber auch das funktionierte nicht. Wenn ich allerdings ein einfaches sleep > > 1000 reinsetze, pausiert er, zieht aber die anderen Threads leistungstechnisch nach unten. > > Hat jemand eine Idee, woran es liegen könnte oder wie ich das Problem elegant umgehen könnte? > > Viele Grüße, > > Mark > > > >