Ich möchte Python ausführen (ähnlich subprocess.Popen()
?) einen externen Socket-Anschluss nachdem ich einen anderen Thread zu blockieren bei socket.accept()
.Machen Sie "socket.accept" in einem Thread vor einem Code in einem anderen Thread ausführen? (python3)
import socket
import threading
import subprocess
host = '0.0.0.0'
port = 3333
def getsock():
server_sock = []
def getsock_server():
sock = socket.socket()
sock.bind((host, port))
sock.listen(1)
accept_return = sock.accept() # *** CRITICAL ACCEPT ***
server_sock.append(accept_return[0])
address = accept_return[1]
return address
thr = threading.Thread(target=getsock_server)
thr.start()
"""Something that *must* be done after the CRITICAL ACCEPT
line is executing and the thread "thr" is blocked. Otherwise
the program malfunctions and blows into some undebuggable
complexity. ;(
Although it is a connect operation, it may not be as innocent
as belowing lines:
client_sock = socket.socket()
client_sock.connect((host, port))
"""
p = subprocess.Popen(
["./connector"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
thr.join()
return server_sock[0]
conn, addr = getsock()
Grundsätzlich muss ich alles wie unten, um arbeiten lassen:
1) thr.start()
2) sock.accept()
3) subprocess.Popen()
Wenn 3) geht vor 2), werden unerwünschte Folge passieren.
Eine Lösung ohne Threads (ich dachte es zuerst definitiv, da Threading mühsam ist ..) ist unmöglich seit ich socket.accept()
kann ich nicht einfach subprocess.Popen()
ohne die Annahme unterbrechen.
Auch ich möchte nicht time.sleep(SOME_LARGE_VALUE)
verwenden, da es auch unkontrollierbar ist (fehleranfällig, verwende ich das richtige Wort?) Und außerdem langsam.
Ich habe gelernt, dass: Python3 (CPython) hat globale Interpreter Lock (GIL) -Mechanik. Zu einem Zeitpunkt hat nur ein Thread die Möglichkeit zur Ausführung. Und wenn ein Thread blockiert (in diesem Fall socket.accept()
), wird CPython zu einem anderen Thread wechseln. (Allerdings hilft das nicht mit dem Problem ..)
Jeder weiß eine pythonische Art und Weise (oder eine nicht-so-Python Art) der Durchsetzung der Reihenfolge?
"unerwünschte Folge"? Wie wäre es, uns einen Hinweis zu geben? Ich konnte sehen, dass ich den Anruf nach dem Hören machen wollte, aber wo genau sollte der Subprozess laufen? Kurz vor dem Akzeptieren, gleich nach dem Akzeptieren? Warum ist es wichtig, dass das Akzeptieren blockiert wird, bevor der Subprozess ausgeführt wird? – tdelaney
Sobald "listen (1)" zurückkehrt, wird der TCP-Stack bis zu 1 Verbindungsanforderung im Hintergrund in Warteschlange stellen, auch wenn Sie noch nicht "accept" aufgerufen haben. Solange Sie 'accept' aufrufen, bevor die andere Seite sich langweilt und ihre Verbindung zurücksetzt, wird die Verbindung hergestellt. – tdelaney
Ich werde es versuchen ... Scheint so, als wäre ich mit Socket-Systemaufrufen weit entfernt ...: P – Thiner