1 #!/usr/bin/env python
2
3 import threading
4 import Queue
5 import time
6 import types
7
8
9 #----------------------------------------------------------------------
10 class WartenderThread(threading.Thread):
11 """
12 Dieser Thread wartet auf die Anweisung, verschiedenste Jobs abzuarbeiten.
13 """
14
15 #----------------------------------------------------------------------
16 def __init__(self, jobqueue, ausschalter):
17 """
18 Übernimmt die Queue, die später die Jobanweisungen übergibt.
19 """
20
21 threading.Thread.__init__(self)
22
23 self.jobqueue = jobqueue
24 self.ausschalter = ausschalter
25
26
27 #----------------------------------------------------------------------
28 def hallo_welt_1(self):
29 """
30 Diese Funktion wird aufgerufen, wenn an die
31 Jobqueue "hallo_welt_1" übergeben wurde.
32 """
33
34 print " Ausgefuehrt: Hallo Welt 1"
35
36
37 #----------------------------------------------------------------------
38 def hallo_welt_2(self, **dargs):
39 """
40 Diese Funktion wird aufgerufen, wenn an die
41 Jobqueue "hallo_welt_2" übergeben wurde.
42 """
43
44 print " Ausgefuehrt: Hallo Welt 2"
45 if dargs:
46 for key, value in dargs.items():
47 print " %s: %s" % (key, value)
48
49
50 #----------------------------------------------------------------------
51 def run(self):
52 """
53 'run' ist die Methode, die aufgerufen wird, wenn 'WartenderThread.start()'
54 ausgeführt wird.
55 """
56
57 # In einer Schleife wird darauf **gewartet** bis ein neuer Job
58 # an die Jobqueue übergeben wird.
59 while True:
60
61 # Hier wird gewartet
62 anweisung = self.jobqueue.get()
63
64 # Diesen Thread kurz schlafen schicken, damit wird auch die
65 # Unabhängigkeit des Threades demonstriert.
66 time.sleep(1)
67
68 print "Anweisung: %s" % str(anweisung)
69
70 # Wenn die Anweisung ein Tupel oder eine Liste ist, dann
71 # wird diese(r) in die Anweisung und die Argumente zerlegt.
72 if isinstance(anweisung, (types.ListType, types.TupleType)):
73 anweisung, dargs = anweisung
74 else:
75 dargs = {}
76
77 # Wenn Quit übergeben wurde, dann darf die Schleife
78 # nicht weitergeführt werden.
79 if anweisung == "quit":
80 print " Ausschalter setzen"
81 self.ausschalter.set()
82 break
83
84 # Prüfen ob die Methode mit dem Namen %(anweisung)s
85 # existiert. Wenn Ja, ausführen.
86 if hasattr(self, anweisung):
87 getattr(self, anweisung)(**dargs)
88
89
90
91 #----------------------------------------------------------------------
92 class AnweisenderThread(threading.Thread):
93 """
94 Dieser Thread gibt Anweisungen an den anderen Thread weiter.
95 """
96
97 #----------------------------------------------------------------------
98 def __init__(self, jobqueue):
99 """
100 Übernimmt die Queue, mit der die Jobanweisungen an den anderen
101 Thread übergeben werden.
102 """
103
104 threading.Thread.__init__(self)
105
106 self.jobqueue = jobqueue
107
108
109 #----------------------------------------------------------------------
110 def run(self):
111 """
112 'run' ist die Methode, die aufgerufen wird, wenn 'AnweisenderThread.start()'
113 ausgeführt wird.
114 """
115
116 # Ein paar Anweisungen in einen Tupel stecken...
117 # "hallo_welt_3" ist nur ein Platzhalter, ohne zugeh. Funktion
118 # im wartenden Thread.
119 anweisungen = ("hallo_welt_1", "hallo_welt_2", "hallo_welt_3")
120
121 # Die ersten Anweisungen in die Queue stellen.
122 for anweisung in anweisungen:
123 self.jobqueue.put(anweisung)
124
125 # Durch diese Wartezeit, sieht man ziemlich gut, dass der wartende
126 # Thread wirklich auf die nächste Anweisung aus der Queue wartet.
127 time.sleep(10)
128
129 # An die Anweisung "hallo_welt_2" werden auch die Parameter
130 # übergeben.
131 anweisungen = (
132 "hallo_welt_1",
133 ("hallo_welt_2", {"vorname": "Gerold", "nachname": "Penz"}),
134 )
135 # Anmerkung: Die Klammern in der Zeile mit hallo_welt_2 beachten! (->Tupel)
136
137 # Die nächsten zwei Anweisungen in die Queue stellen.
138 for anweisung in anweisungen:
139 self.jobqueue.put(anweisung)
140
141 # Die Anweisung zum Beenden schicken.
142 self.jobqueue.put("quit")
143 return
144
145
146
147 #----------------------------------------------------------------------
148 def main():
149 """
150 Startet die Threads und führt den Test durch.
151 """
152
153 # Jobqueue erstellen (Queue)
154 q = Queue.Queue()
155
156 # Ausschalter erstellen (Event)
157 ausschalter = threading.Event()
158
159 # Threads initialisieren und dabei die Jobqueue und den
160 # Ausschalter übergeben
161 wt = WartenderThread(q, ausschalter)
162 at = AnweisenderThread(q)
163
164 # Threads starten
165 wt.start() # Dieser wartet so lange bis Jobanweisungen geschickt werden.
166 at.start() # Dieser schickt Jobanweisungen über die Jobqueue.
167
168 # Warten bis der Ausschalter betätigt wurde. Sonst würde das
169 # Programm sofort beendet werden.
170 ausschalter.wait()
171
172
173 #----------------------------------------------------------------------
174 if __name__ == "__main__":
175 main()
Aus dem Forum, von gerold geschrieben: http://www.python-forum.de/viewtopic.php?p=32526#32526