borg Geschrieben July 24, 2012 at 17:57 Geschrieben July 24, 2012 at 17:57 Mh, verstehe ich nicht. Wir blocken ja an der Stelle mit einer Semaphore und sobald wir blocken sollte die JVM schedulen. Oder nicht? Zitieren
chariowalda Geschrieben July 24, 2012 at 19:12 Geschrieben July 24, 2012 at 19:12 Im Grunde schon *gruebel* Also, nur um mein momentanes Verständnis mal zu validieren, die IPconnection und addDevice Methodik läuft wie folgt: [*]Initialisieren der IPConnection, damit werden die Streams zum brickd geöffnet, die CallbackLoop und der Receiver-Thread gestartet. [*]Device (z.B. TemperatureIR) wird instanziert und damit eine Sende- und eine Empfangs-Semaphore erstellt (die Queue lass ich mal fallen). Die Empfangs-Semaphore wird gleich mal mit einem aquire "belastet" und die UID decoded. Der Konstruktor registriert dann noch seine spezifischen Callback-Listener und fertig. [*]Per addDevice wird im Grunde nun eine Art "ping - bist Du da?"-Message an den brickd geschickt. [*]Dann wird mit einem tryAcquire auf eine Antwort gewartet. [*]Sendet der brickd die Antwort, dann wird sie vom Receiver-Thread aufgegriffen. Der gibt die Nachricht wieder in die IPConnection (handleMessage) und wenn dort erkannt wird, dass es die Antwort zu einer "ping - bist Du da?"-Message ist, dann wird der addDevice-Vorgang durch den Aufruf von handleAddDevice abgeschlossen. [*]In handleAddDevice wird geschaut ob die Message zum letzten hinzugefügten addDevice-Aufruf passt. Wenn ja, dann wird das Device "registriert" und die Semaphore released. [*] Der wartende Haupt-Thread kann jetzt weiter machen. Ich hoffe ich habe nicht zu viele Dinge unter den Tisch fallen lassen, aber im Groben müsste das passen. Das einzige wo ich ins Grübeln gekommen bin ist beim Punkt 6. Wenn ich eine "ping - bist Du da?"-Antwort-Message bekomme die nicht zu meine Gerät passt, dann wird diese einfach verworfen und weiter darauf gewartet, dass eine passende Message kommt. Würde nun noch ein addDevice gemacht, dann wird das vorher in der Variable addDevice gehaltene Device überschrieben und auf dessen Registrierung gewartet. Klingt grundsätzlich alles nicht wirklich falsch. Und wie da ein sleep(1) Wunder wirkt, keine Ahnung. Und jetzt ärgere ich mich, dass meine RPi beim Freund an der Solaranlage hängt und nicht vor mir liegt. Schönen Abend noch, #arald Zitieren
photron Geschrieben July 24, 2012 at 20:13 Geschrieben July 24, 2012 at 20:13 Das ist alles soweit richtig. Es haben sich aber in der letzten Version der Java Bindings einige Detail beim Locking geändert. - Die semaphoreAnswer wurde entfernt und deren Funktion über die responseQueue realisiert. - addDevice ist jetzt thread-safe. Vorher konnten mehrere Threads gleichzeitig addDevice auf eine IPConnection aufrufen und sich gegenseitig die pendingAddDevice Variable überschreiben. Das ist jetzt verbessert. Das hat aber alles hier für diese Problem keine Auswirkung. Wenn das sleep(1) dazuführt, dass Linux einen anderen Prozess scheduled, dann vielleicht ja auch brickd. Und wenn das nicht passiert dann passiert ... keine Ahnung Daher meine Frage ins Blaue, ob das Problem auch auftritt, wenn das Java Programm auf dem R-Pi ist und der brickd auf einem anderen Rechner. Wenn es dann ohne sleep(1) geht heißt dass ... bin ich mir gerade nicht sicher was das dann sagen will. Wie du siehst mehr Fragen als Antworten Zitieren
AuronX Geschrieben July 25, 2012 at 07:25 Geschrieben July 25, 2012 at 07:25 Sagen wir es so, Sleeps yields usw wild einfügen und entfernen sind typische Methoden um Threading-Fehler im eigenen Code zu entlarven. Vielleicht ist der neue Code noch fehlerhaft? Ich habe noch nicht reingeschaut, deswegen ist das eine böse Unterstellung von mir. Aber beispielsweise sind nahezu alle heutigen Desktop PCs Multi-Core, der RPi bestimmt nicht. Insofern würde es mcih nciht wundern, wenn der Threading-Fehler findet die vorher keiner gesehen hat. Ich tauche nachher mal in den Code, falls jemand schneller ist kann er ja mal folgendes Testen: Im Windows-Task-Manager (Linux kann sowas bestimmt auch) die CPU-Affinität des Java-Prozesses auf nur eine CPU einschränken, damit wird das Programm Single-Core ausgeführt. Dazu sollte das Programm auf eine Nutzereingabe oder so warten bevor es mit addDevice beginnt um genug zeit zu verschaffen die Affinität zu verändern. edit: Ich sehe auf den ersten Blick auch keine Fehler im Locking (angenommen die SychronousQueue wird von jeder Standardbibliothek korrekt implementiert) Okay, eine Sache ist mir aufgefallen, diese kann zu dem Verhalten führen, dass bei zwei hintereinander kommenden AddDevice das zweite fehlschlägt. handleAddDevice endet so: try { pendingAddDevice.responseQueue.put(packet); } catch(InterruptedException e) { e.printStackTrace(); } pendingAddDevice = null; und der gelockte block von adddevice beginnt so: synchronized(addDeviceMutex) { pendingAddDevice = device; Ich führe den Code jetzt mal böse aus: AddDevice #1 wartet auf response HandleAddDevice #1 wird abgearbeitet und nach dem putten in die resp-queue dessen Thread unterbrochen AddDevice #1 wird fertig (resp-queue gefüllt) AddDevice #2 beginnt, setzt pendingDevice und wartet auf Antwort HandleAddDevice #1 beendet sich, setzt pendingDevice auf null HandleAddDevice #2 wird ausgeführt, aber das pendingDevice ist null, also wird nix getan. Ich denke eine sinnvolle Lösung wäre es, das pendingAddDevice im sync-block der Methode AddDevice zu nullen. Zitieren
photron Geschrieben July 25, 2012 at 08:06 Geschrieben July 25, 2012 at 08:06 AuronX, ich gebe dir mit deiner Analyse voll recht! Angehängt eine Version in der das Problem behoben sein sollte zum Testen.tinkerforge_java_bindings_1_0_15_add_device_race_fixed.zip Zitieren
Nic Geschrieben July 25, 2012 at 08:14 Geschrieben July 25, 2012 at 08:14 Falls nicht schon gelöst, ev. hilft das weiter: http://www.raspberrypi.org/phpBB3/viewtopic.php?f=2&t=5326 Zitieren
AuronX Geschrieben July 26, 2012 at 14:46 Geschrieben July 26, 2012 at 14:46 Frage an Threadersteller: Problem dadurch gelöst? Frage an photron (wahlweise TF): Mindestens in den C#-Bindings besteht der gleiche Fehler... unabhängig davon ob es in diesem Foren-Thread die Ursache ist, sollte er denke ich überall gefixed werden. Zitieren
chariowalda Geschrieben July 27, 2012 at 06:34 Geschrieben July 27, 2012 at 06:34 Ich bin zwar nicht der Threadersteller, aber da ich das gleiche Problem hatte, werde ich das auf jeden Fall Testen. Farnell hat den bisherigen Rekord, meine 10 bestellten RPis sind bereits da - Dienstag bestellt, gestern angekommen. Damit ich wieder testfähig bin, werde mir heute noch 'ne SD-Card holen und erstmal die "alte" Version installieren. Damit sollte das Problem ja reproduzierbar sein. Dann die neue Version und dann werde ich mich wieder melden. Have fun, #arald Zitieren
Nic Geschrieben July 27, 2012 at 10:33 Geschrieben July 27, 2012 at 10:33 @chariowalda Das wäre prima, dann kommen wir hoffentlich hier zu einem guten Ende und die Sache ist schnell vom Tisch. PS: Möchte nicht indiskret sein, wozu brauchst Du 10 RaspPis ? Zitieren
chariowalda Geschrieben July 27, 2012 at 10:41 Geschrieben July 27, 2012 at 10:41 SD-Card ist gekauft, daher kann es heute Abend getestet werden (oder ich bekomme Hitzefrei, dann vorher :. Tja, wofür braucht man 10 RPis. 1 x Testen/TF (meine hängt ja beim Freund an der Solaranlage) 1 x XMBC 2 x Kollege 2 x Schülerpraktikanten bleiben 4 für Spielereien. Gib mir 2 Wochen und sie sind verbaut Zitieren
Nic Geschrieben July 27, 2012 at 11:34 Geschrieben July 27, 2012 at 11:34 @chariowalda Lies mal bitte mein neues Topic zum RaspPi, vielleicht hast du ein paar Tips für mich: http://www.tinkerunity.org/forum/index.php/topic,757.msg5047.html#msg5047 Zitieren
chariowalda Geschrieben July 27, 2012 at 20:10 Geschrieben July 27, 2012 at 20:10 Gute Nachrichten. (1) Ich habe mit einer RPi und dem alten JAR den alten Stand reproduzieren können. Mehrfache Versuche, mit und ohne Systemlast, immer das identische Ergebnis -> Exceptions durch addDevice. (2) Sleep eingefügt, gleiche Tests wie unter (1), funktioniert. (3) Sleeps entfernt, neue JAR Datei genommen (hier aus dem Thread), gleiche Tests wie in (1) und (2), alles Gut! Frohes Schwitzen noch ... have fun #arald Zitieren
photron Geschrieben July 30, 2012 at 14:50 Geschrieben July 30, 2012 at 14:50 Frage an photron (wahlweise TF): Mindestens in den C#-Bindings besteht der gleiche Fehler... unabhängig davon ob es in diesem Foren-Thread die Ursache ist, sollte er denke ich überall gefixed werden. Richtig, das Problem bestand in allen Bindings und ich habe gerade den Fix committed. Neue Binding Releases gibt es morgen, denke ich. Zitieren
photron Geschrieben August 1, 2012 at 16:35 Geschrieben August 1, 2012 at 16:35 Korrigierte Bindings sind verfügbar. Zitieren
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.