Ich brauche eine Interthreadkommunikation zwischen einen Worker-Thread (A) und einem Urwid-GUI-Thread (B) (siehe http://www.python-forum.de/topic-19633.html ).
Die Kommunikation geht in zwei Richtungen:
(B) -> (A)
Um Befehle, die am GUI eingegeben werden, an den Worker-Thread weiterzuleiten, werde ich Queue.Queue nehmen.
(A) -> (B)
Logging, stdout und stderr des Worker-Threads müssen für die Darstellung im GUI zum Urwid-Thread transportiert werden. Hier bietet sich denke ich eine os.pipe() - Lösung an (für andere Vorschläge bin ich natürlich offen ) Nehmen wir also für die folgenden Fragen einfach an, dass ich auf der schreibenden Seite einer os.pipe() regelmäßig irgendwelche Strings mit os.write() reinstopfe. Jetzt habe ich zwei Fragen zum weiteren Vorgehen:
[1] Was bedeutet es, wenn select() den lesenden FD returned?
Urwid hat eine SelectEventLoop, die ich im Zusammenhang mit dem lesenden Ende der Pipe benutzen möchte. Das Ganze basiert auf select.select() und es wird eine callback-Funktion losgetreten, wenn ein filedeskriptor.. und hier weiß ich nicht weiter. Was heißt es, wenn der lesende FD an select() übergeben wird und returned wird? Insbesondere: Sind dann Daten da oder nicht? Was wird der nächste os.read()-Aufruf bringen? Kann os.read() blockierend sein?
Was ich hierzu gelesen habe:
In der Pythondocs Intro zu select:
Das ist ja eigentlich genau das, was ich machen will. Nur: ich habe ja keine "regular files", sondern ne pipe. Was sagt mir das jetzt?It cannot be used on regular files to determine whether a file has grown since it was last read.
Trundle in http://www.python-forum.de/topic-18022,15.html:
Wenn das generell so stimmt, ist das Mist für mich; andererseits stelle ich mir dann die Frage, was mit dem FD los sein muss, damit select() ihn nicht returned. Wann passiert das? Und ich stelle mir die Frage, warum urwid eine SelectEventLoop auf select() basierend hat, wenn select() nicht aussagt, ob Daten vorliegen oder nicht.Jetzt habe ich eben geschrieben, dass `select()` dir zurückgibt, ob man von der Pipe lesen kann, nicht aber, ob Daten vorliegen.
Wenn select mir nicht sagt, ob Daten vorliegen -- gibt es eine andere Methode?
Irgend ein Typ bei Stackoverflow ( http://stackoverflow.com/questions/3238 ... -in-python ):
mit der Frage: "How to find out if there is data to be read from stdin[..]?"This code
select.select([sys.stdin], [], [], 1.0)
does exactly what I want on Linux
Das macht mir also wieder Hoffnung, dass select.select() und damit die SelectEventLoop das ist, was ich brauche.
[2] Inwiefern ist os.pipe().read()/write() eigentlich thread safe?
Was passiert, wenn ein lesender und schreibender Zugriff beider Threads gleichzeitig auf die selbe pipe erfolgt? Ich denke, dass Pipes vom Prinzip her threadsafe sein sollten, aber eine Bestätigung dessen habe ich irgendwie nicht gefunden bisher..