【发布时间】:2017-06-18 14:20:42
【问题描述】:
我希望 python 执行(类似于 subprocess.Popen()?)一个外部套接字连接器,因为我在 socket.accept() 有另一个线程要阻塞。
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()
基本上,我需要按如下顺序完成所有工作:
1) thr.start()
2) sock.accept()
3) subprocess.Popen()
如果 3) 先于 2),就会产生不良后果。
没有线程的解决方案(我首先认为它是肯定的,因为线程很麻烦..)是不可能的,因为当我 socket.accept() 我不能只是 subprocess.Popen() 而不中断接受。
我也不想使用time.sleep(SOME_LARGE_VALUE),因为它也是无法控制的(容易出错,我使用的词是否正确?)而且速度很慢。
我了解到:Python3 (CPython) 具有全局解释器锁定 (GIL) 机制。一次只有一个线程有机会执行。如果一个线程阻塞(在本例中为socket.accept()),CPython 将转向另一个线程。 (但是,这对解决问题没有帮助..)
有人知道执行命令的 Python 方式(或不那么 Python 方式)吗?
【问题讨论】:
-
“不良后果”?给我们一个提示怎么样?我可以看到想要在听后进行调用,但是子进程应该在接受中的哪个位置运行?就在接受之前,就在接受之后?为什么在子进程运行之前接受阻塞很重要?
-
一旦
listen(1)返回,即使您还没有调用accept,TCP 堆栈也会在后台排队最多1 个连接请求。只要你在对方感到无聊并重置连接之前调用accept,它就会完成连接。 -
我会试一试...好像我对套接字系统调用很不熟悉...:P
-
但是,如果发生另一种这样的情况(需要先进行阻塞操作,然后再进行另一个操作),那么 Pythonic/nonpythonic 解决方案是什么?
标签: python multithreading sockets