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 > > > > > > > > > > > > Hiermit könnte es gehen. > > > > <code> > > long solldrehzahl,timer; > > byte versuche,minimaledrehzahl; > > thread Motorstarten > > { > > wait global.startmotor; > > global.startmotor = 0; > > global.startok = 0; > > ports.set(1,1); // Port an dem der Starter des Motors hängt > > versuch = 1; > > timer = system.timer(); > > sleep 100; > > loop > > { > > if ports.getfreq(2) >= solldrehzahl // Port an dem der Drehzahlmesser hängt > > { > > global.startok = 1; > > > > break; > > } > > if system.timer()-timer>=5000 > > { > > if ports.getfreq(2) >= solldrehzahl // Port an dem der Drehzahlmesser hängt > > { > > global.startok = 1; > > break; > > } > > else > > { > > if versuche >= 3 > > { > > global.startok = 2; > > break; > > } > > sleep 10000; > > ports.set(1,1); // Port an dem der Starter des Motors hängt > > versuch = versuch + 1; > > timer = system.timer(); > > } > > } > > > > } > > > > > > } > > > > > > > > thread main > > { > > run Motorenstart; > > } > > </code> > > > > Es muss aber die Solldrehzahl definiert werden. Ich habe mal angenommen das sie als Frequenz anliegt. > > Man braucht auch ein Modul Global wo die Variablen startmotor und startkok enthalten sind. > > Wenn die Variable global,startmotor ungleich 0 wird dann wird der motor gestartet. > > Die Fehlermeldung wird über global.startok übertragen. Wenn das Ergebnis 1 ist dann ist alles ok, > > bei 2 ist der Motor nach 3 Versuchen nicht angelaufen. > > Als Pause zwischen den Anläufen wurden 10 sec gewählt. > > > > Gruss JackFrost > > Ups falscher Thread :( > > Bitte löschen wenn es geht. > > Gruss JackFrost