Crash-Safe Multithreading?



  • Hallo,
    das unterhaltsamste Problem der Woche ist: Ich muss eine Hardware-nahe Library als Interface verwenden. Es gibt weder den Quellcode, noch eine MD kompilierte Release-Version und sie crasht ungefähr alle 10 Minuten. Da die Library aus zwei C-Funktionen besteht, und so einfach zu bedienen ist, wie ein Staubsauger, überlege ich folgenden Ansatz:

    Ich lagere die Calls der zweiten Library in einen externen Prozess aus, der über boost message_queue die Daten an meinen Hauptprozess schickt.

    Meine Idee: Wenn der zweite Prozess crasht, startet das Hauptprogramm ihn neu.

    Wie kann ich jetzt herausfinden, ob ein Thread gecrasht ist, oder muss ich das an den Daten, die er übermittelt, ausmachen?



  • Hobo schrieb:

    Meine Idee: Wenn der zweite Prozess crasht, startet das Hauptprogramm ihn neu.

    Wie kann ich jetzt herausfinden, ob ein Thread gecrasht ist,

    Was denn nun? Beim Prozess würd ichs an den Daten ausmachen: Ping das Ding immer wieder mal an, wenn er sich nicht meldet, sicherheitshalber killen und neu starten.



  • Hey, danke für die Antwort. Ich habe das Problem erstmal über Boost-Interprocess gelöst, das heißt, sowohl die Daten als auch der Ping werden über shared_memory gespeichert.

    Mein Ping ist zur Zeit so gebaut, dass Child-Process in seinem Infinite Main-Loop jedesmal time() aufruft, und die Variable in den Shared Memory speichert.

    Wenn Host-Process bemerkt, dass die Variable länger nicht geupdated wurde, killt und resetted er Child-Process.

    Problem ist: Wenn Child-Process startet, dauert es undefiniert lang bis zum ersten time() und wird manchmal infinit neugestartet. Abhilfe kann hier natürlich eine konstante Variable schaffen, z.B. dass die Überprüfung des Updates nach Child-Start erstmal zwei Sekunden ausgesetzt bleibt.

    Je nach Prozessor-Geschwindigkeit kann das natürlich schief gehen (wenn der Rechner langsam ist und lange braucht).

    Für interne Testzwecke reichts erstmal so.

    Zuletzt fällt mir noch ein, Child-Prozess eine geteilte bool auf 1 setzen zu lassen, wenn er gestarted ist. Bevor die Variable true ist, kann Host ihn nicht kicken. Wenn Host ihn kickt, setzt er sie wieder auf false.

    Gibts elegantere Wege?
    Lg..



  • Hobo schrieb:

    Problem ist: Wenn Child-Process startet, dauert es undefiniert lang bis zum ersten time() und wird manchmal infinit neugestartet. Abhilfe kann hier natürlich eine konstante Variable schaffen, z.B. dass die Überprüfung des Updates nach Child-Start erstmal zwei Sekunden ausgesetzt bleibt.

    [...]
    Zuletzt fällt mir noch ein, Child-Prozess eine geteilte bool auf 1 setzen zu lassen, wenn er gestarted ist. Bevor die Variable true ist, kann Host ihn nicht kicken. Wenn Host ihn kickt, setzt er sie wieder auf false.

    Die geteilte bool kann doch einfach der besagte Timestamp sein. Der Host setzt den Inhalt des Timestamp auf 0, und solange er 0 ist, weiß er, dass der Childprozess noch nicht aus den Puschen gekommen ist. Sobald was drinsteht wird abgeglichen und bei zu langer Wartezeit gekickt (und wieder null gesetzt).



  • Ich verstehe nicht was das ganze jetzt mit Multithreading zu tun hat.
    Wenn die Library nicht mit Runtime X gebaut ist, dann muss das Programm eben auch Runtime X verwenden. Und wenn diese Runtime X nicht threadsafe ist, dann darf es in den Programm eben keine Threads geben.

    Dein ausgelagerter Worker-Prozess dürfte dann also gar nicht mehr crashen.

    Wenn er das doch tut, dann ist irgendwo der Hund drinnen. Dann ist die Variante mit Prozess killen + neu starten vielleicht ein "netter" Workaround, aber du wirst nie sicher sein können dass nicht doch irgendwann schlimme Dinge passieren. z.B. kein Crash aber falsche Daten.



  • Hobo schrieb:

    Hallo,
    das unterhaltsamste Problem der Woche ist: Ich muss eine Hardware-nahe Library als Interface verwenden. Es gibt weder den Quellcode, noch eine MD kompilierte Release-Version und sie crasht ungefähr alle 10 Minuten. Da die Library aus zwei C-Funktionen besteht, und so einfach zu bedienen ist, wie ein Staubsauger, überlege ich folgenden Ansatz:

    Ich lagere die Calls der zweiten Library in einen externen Prozess aus, der über boost message_queue die Daten an meinen Hauptprozess schickt.

    Meine Idee: Wenn der zweite Prozess crasht, startet das Hauptprogramm ihn neu.

    Wie kann ich jetzt herausfinden, ob ein Thread gecrasht ist, oder muss ich das an den Daten, die er übermittelt, ausmachen?

    Wende dich besser an der Hersteller der Library, das der Crash gefixt wird.


Anmelden zum Antworten