Python: Socket und Threads?

8

Ich habe ein Designproblem:

Ich habe zwei Threads, einen Heartbeat / Control-Thread und einen Messagehandler-Thread.

Beide teilen sich den gleichen Socket, aber der messageHandler-Thread sendet nur Nachrichten und empfängt niemals. Der Heartbeat-Thread sendet und empfängt (empfängt Nachrichten und reagiert auf Herzschläge).

Das Problem ist, ich bin mir nicht sicher, ob das sicher ist. Es gibt keinen Mechanismus, den ich selbst implementiert habe, um zu sehen, ob der Socket benutzt wird. Ist das Teilen eines Sockets über Python automatisch threadsicher oder nicht?

Auch wenn es nicht der Fall ist, liegt der Grund, warum ich sie in einen separaten Thread gesetzt habe, darin, dass der Heartbeat wichtiger ist als die Nachrichtenbehandlung. Dies bedeutet, dass wenn es mit Nachrichten überschwemmt wird, es immer noch einen Herzschlag machen muss. Also, wenn ich eine Schraube implementieren muss, kann ich priorisieren, wenn mein Heartbeat / Control Thread einen Heartbeat senden muss?

    
Lucas Kauffman 24.06.2012, 11:21
quelle

4 Antworten

4

Leider ist der von Multithread freigegebene Socket nicht threadsicher. Denken Sie über den Puffer nach, den zwei Threads ohne Sperre verarbeiten.

Der normale Weg zu implementieren ist mit zwei Sockets, genau wie ftp.cmd socket und msg socket.

Wenn Sie dies durch einen Socket implementieren möchten, können Sie verschiedene Typen von Nachrichten in verschiedene Warteschlangen einfügen und mit einem dritten Thread die Warteschlange konsumieren und sie über den einzigen Socket senden.

Auf diese Weise können Sie die Heartbeat-Nachrichten prior zu Datennachrichten steuern.

    
yancl 24.06.2012, 11:59
quelle
8

Ein besserer Weg als die Verwendung eines dritten Threads ist die Verwendung von threading.Lock() , um die Socket-Ressource zu schützen, da dadurch kein dritter Thread mehr benötigt wird. Sie haben weniger Aufwand und weniger Latenz als bei einem dritten Thread.

%Vor%

Sie können das aus einem Ihrer Threads aufrufen, aber nur ein Thread gleichzeitig kann sock.send aufrufen. Wenn ein Thread die Sperre erreicht, die bereits von einem anderen Thread gesperrt wurde, wird er in den Ruhezustand versetzt, bis der andere Thread die Sperre aufgibt. Anschließend wird die Sperre übernommen und der Prozess wird wiederholt.

Das Threading-Modul enthält Lock , RLock und Condition , die alle sehr nützlich sind, wenn Sie mit mehreren Threads arbeiten. Sie werden es sehr schätzen, sich mit ihnen und ihrer Verwendung vertraut zu machen.

Sie könnten den Heartbeat in Ihre Nachrichtenbehandlung integrieren, indem Sie die aktuelle Uhrzeit mit dem letzten Sendezeitpunkt vor dem Verarbeiten jeder Nachricht überprüfen und verhindern, dass Nachrichten überflutet werden, die dazu führen, dass kein Heartbeat gesendet wird. Das Problem ist, wenn der Code zur Nachrichtenverarbeitung nicht ausgeführt wird, werden keine Heartbeats gesendet. Sie können dies abmildern, indem Sie Ihren Message-Handling-Code eine Dummy-Nachricht über das Intervall erhalten lassen, damit dieser prüfen kann, ob er einen Heartbeat senden muss und einfach die Dummy-Nachricht ignorieren muss.

Sie sollten versuchen, Threads sparsam zu verwenden (zielen Sie auf einen einzelnen Thread), aber in Ihrem Fall wäre ein Thread wahrscheinlich in Ordnung, da er die meiste Zeit damit verbringen wird zu schlafen. Sie sollten jedoch keinen Daemon-Thread verwenden, da sie nicht ordnungsgemäß heruntergefahren werden. Obwohl der Schaden in Ihrem Fall nicht vorhanden sein kann, wenn er nicht ordnungsgemäß heruntergefahren wurde, kann er dennoch einen Fehler (Fehlermeldung) auslösen, der schlecht aussieht.

Ich stimme der Multiple-Sockets-Methode nicht zu, da ich denke, dass dies die Situation komplizieren würde. Sie werden viele Arten von Netzwerkdiensten / Anwendungen finden, die den Heartbeat und die Nachrichten in einen einzelnen Byte-Datenstrom integrieren.

    
kmcguire 27.09.2014 02:49
quelle
0

Ich kenne keine Möglichkeit, auf der Python-Ebene Prioritäten zu setzen.

Ich würde also vorschlagen, zwei Prozesse zu verwenden, keine Threads und Prioritäten auf Betriebssystemebene. Unter Unix können Sie dazu os.nice () verwenden.

Sie müssten dann 2 Sockets verwenden und Ihr Problem mit der Freigabe würde gleichzeitig gelöst.

    
uselpa 24.06.2012 11:28
quelle
0

Wenn beide Threads Client-Threads sind, ist es eine gute Idee, zwei Client-Sockets für den Heartbeat-Server und einen für die Kommunikation zu öffnen.

    
Tariq Mehmood 24.06.2012 11:39
quelle

Tags und Links