wie mit Daemon-Threads umgehen?

26/08/2009 - 22:56 von Thomas Rachel | Report spam
Hallo,

ich beschàftige mich gerade mit Threads unter Python 2.6.

Bekanntlich gibt es Daemon-Threads, die mit dem Hauptthread sterben, und
Nicht-Daemon-Threads, auf die der Hauptthread vor dem Beenden wartet.

Nun stellt sich gelegentlich die Frage, welche der Möglichkeiten nimmt
man wahr:

1. arbeite mit daemon==False

Hier besteht die Gefahr, daß ich bei unsauberer Programmierung (ja, ich
weiß, die sollte man vermeiden...) am Ende des Programms in ein Deadlock
laufe, weil ein Thread noch làuft und gefüttert werden will, das
Hauptprogramm aber schon, àh, auf dem Nachhauseweg ist.


2. arbeite mit daemon==True

Die sterben, wenn der Hauptprozeß geht. Ohne wenn und aber. Das ist zwar
gut fürs Beenden an sich, aber sie sterben so abrupt, daß sie "Unrat
hinterlassen": entweder sie werfen etwas wie

Exception in thread writethread (most likely raised during interpreter
shutdown):
Traceback (most recent call last):
File "/usr/lib/python2.6/threading.py", line 522, in __bootstrap_inner
File "/usr/lib/python2.6/threading.py", line 477, in run
File "pipesync.py", line 703, in _writethread
File "/usr/lib/python2.6/threading.py", line 205, in __enter__
File "/usr/lib/python2.6/threading.py", line 115, in acquire
<type 'exceptions.TypeError'>: 'NoneType' object is not callable

, oder sie verrecken an einem Speicherzugriffsfehler. (BTDT)

Nun ist die Frage: Kann man dagegen etwas zuverlàssiges tun? Eine
Exit-Routine über das Modul atexit oder so, die das Verhalten von
threading._shutdown aka threading._MainThread()._exitfunc nachahmt, d.h.
die Nicht-Dàmonisierung emuliert?

Grad noch ne Frage, weils grad paßt: Wir funktioniert das in threading?
Dieses Modul registriert seine _shutdown nirgends, andererseits scheint
die dennoch aufgerufen zu werden. In einem eigenen Modul ein _shutdown
hinterlegt, brachte jedoch nichts. Hö? -- Wie auch immer, für mich gilt
dann wohl atexit.

TIA,


Thomas
 

Lesen sie die antworten

#1 Diez B. Roggisch
27/08/2009 - 12:01 | Warnen spam
Thomas Rachel wrote:

Hallo,

ich beschàftige mich gerade mit Threads unter Python 2.6.

Bekanntlich gibt es Daemon-Threads, die mit dem Hauptthread sterben, und
Nicht-Daemon-Threads, auf die der Hauptthread vor dem Beenden wartet.

Nun stellt sich gelegentlich die Frage, welche der Möglichkeiten nimmt
man wahr:

1. arbeite mit daemon==False

Hier besteht die Gefahr, daß ich bei unsauberer Programmierung (ja, ich
weiß, die sollte man vermeiden...) am Ende des Programms in ein Deadlock
laufe, weil ein Thread noch làuft und gefüttert werden will, das
Hauptprogramm aber schon, àh, auf dem Nachhauseweg ist.


2. arbeite mit daemon==True

Die sterben, wenn der Hauptprozeß geht. Ohne wenn und aber. Das ist zwar
gut fürs Beenden an sich, aber sie sterben so abrupt, daß sie "Unrat
hinterlassen": entweder sie werfen etwas wie

Exception in thread writethread (most likely raised during interpreter
shutdown):
Traceback (most recent call last):
File "/usr/lib/python2.6/threading.py", line 522, in __bootstrap_inner
File "/usr/lib/python2.6/threading.py", line 477, in run
File "pipesync.py", line 703, in _writethread
File "/usr/lib/python2.6/threading.py", line 205, in __enter__
File "/usr/lib/python2.6/threading.py", line 115, in acquire
<type 'exceptions.TypeError'>: 'NoneType' object is not callable

, oder sie verrecken an einem Speicherzugriffsfehler. (BTDT)

Nun ist die Frage: Kann man dagegen etwas zuverlàssiges tun? Eine
Exit-Routine über das Modul atexit oder so, die das Verhalten von
threading._shutdown aka threading._MainThread()._exitfunc nachahmt, d.h.
die Nicht-Dàmonisierung emuliert?



Das sie Unrat hinterlassen ist doch ok - wenn du vorher versucht hast,
sie "ordentlich" zu beenden, d.h. zb einen Sentinel in eine Worker-Queue
geschoben hast und angemessen darauf gewartet, dass die Threads sich
beendet haben.

Wenn das zu lange gedauert hat, dann beendest du dein Programm
halt "Gewaltsam", und damit ist dann eine solche Meldung IMHO auch
vertretbar.



Grad noch ne Frage, weils grad paßt: Wir funktioniert das in threading?
Dieses Modul registriert seine _shutdown nirgends, andererseits scheint
die dennoch aufgerufen zu werden. In einem eigenen Modul ein _shutdown
hinterlegt, brachte jedoch nichts. Hö? -- Wie auch immer, für mich gilt
dann wohl atexit.



Ich habe das jetzt nicht nochmal nachgeschaut, aber es ist tatsaechlich ein
atexit-handler. Wo genau der registriert wird kann ich dir nicht sagen,
irgendwann vor Jahren bin ich darueber mal gestolpert. Ich denke mal das
passiert im builtin "thread"

Diez

Diez

Ähnliche fragen