Zum Server: Das importierte `array` wird nicht verwendet.
Auf Modulebene sollte man nur Code stehen haben der Konstanten, Funktionen und Klassen definiert und nicht das Hauptprogramm. Das verwindet normalerweise in einer `main()`-Funktion die mit folgendem Idiom aufgerufen wird:
Dann kann man das Modul importieren, ohne dass das Programm los läuft, oder man kann es als Programm ausführen.
Was auf Modulebene keinesfalls stehen sollte, sind Variablen die von irgendwo mittels ``global``-Deklaration überschrieben werden. Vergiss am besten gleich dass es ``global`` überhaupt gibt. In diesem Fall kann man zum Beispiel ein `Event`-Objekt herum reichen.
Namenschreibweisen und Leerzeichen- und zeilensetzung entsprechen teilweise nicht dem
Style Guide for Python Code.
Klassennamen fangen danach mit einem Grossbuchstaben an. Überhaupt: Was soll dieses unsinnige `my` bei den Namen?
`Thread`-Objekte haben schon einen Namen den man ihnen geben kann. Und was soll die ID? Grundsätzlich hat jedes Objekt bereits eine ID.
Die ”Linienkommentare” unter den ``class``-Zeilen ist sehr ungewöhnlich und stört beim lesen.
`Timer` erscheint mir kein passender Name für das was die Klasse tut und überhaupt ist eine Klasse hier überdimensioniert. Man kann mit `Thread`-Exemplaren auch Funktionen asynchron ausführen. Da braucht man keine triviale Klasse für zu schreiben.
Wenn eine ``while``-Schleife als erstes ein ``if`` enthält was die Schleife abbrechen kann, dann kann man die Bedingung auch gleich für ``while`` verwenden.
Durchnummerieren von Namen ist in der Regel ein Zeichen das man eigentlich eine Datenstruktur verwenden möchte. Oder im Fall von `thread1` und `thread2` das man die vernünftig benennen sollte, nämlich so das man am Namen erkennt was der Wert bedeutet und nicht nur das es ein Thread ist. Namen sollte man auch nicht abkürzen wenn es keine gebräuchliche Abkürzung ist. `connection` ist klarer als `conn` und `message` sicherlich weniger kryptisch als `msg`.
`time.ctime()` braucht man die aktuelle Zeit nicht zu übergeben, das ist der Default wenn nichts übergeben wird.
Einer der drei Threads ist zu viel. Warum das bedienen der Clients nicht im Hauptthread erledigen?
Beim schliessen der Verbindung und dem Setzen des Flags wäre es robuster wenn man das mit einem ``try``/``finally`` absichert.
Ich komme dann ungefähr bei so etwas heraus (ungetestet):
Code: Alles auswählen
#!/usr/bin/python
# Listener example using two threads
# -- listen for client messages, passing 'close' will terminate all
# -- repeating printing time message (test purpose)
from __future__ import print_function
import time
from multiprocessing.connection import Listener
from threading import Event, Thread
def print_time(exit_event, name, delay):
print('Starting', name)
try:
while not exit_event.is_set():
time.sleep(delay)
print('{0}: {1} {2}'.format(name, time.ctime(), delay))
finally:
print('Exiting', name)
def serve(exit_event, name):
address = ('192.168.1.2', 6000)
listener = Listener(address, authkey='secret password')
try:
while True:
connection = listener.accept()
message = connection.recv()
if message == 'close':
connection.close()
print(
'{0}: connection closed from {1}'.format(
name, listener.last_accepted
)
)
break
#
# process the incoming message...
#
print(
'{0}: connection accepted {1} {2}'.format(
name, listener.last_accepted, message
)
)
finally:
exit_event.set()
listener.close()
def main():
exit_event = Event()
Thread(target=print_time, args=(exit_event, 'myTimer', 2)).start()
serve(exit_event, 'myListener')
print('Exiting Main Thread')
if __name__ == '__main__':
main()