我希望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()
基本上,我需要按以下顺序进行工作:
^{pr2}$如果3)在2)之前,就会产生不良后果。在
没有线程的解决方案是不可能的(我首先肯定地认为,因为线程是麻烦的….)因为当我socket.accept()
我不能在不中断接受的情况下subprocess.Popen()
。在
另外,我不想使用time.sleep(SOME_LARGE_VALUE)
,因为它也是不可控制的(容易出错,我使用的词是否正确?)而且,速度慢。在
我了解到:Python3(CPython)有全局解释器锁(GIL)机制。一次只有一个线程有机会执行。如果一个线程阻塞(在本例中是socket.accept()
),CPython将转向另一个线程。(但是,这无助于解决问题….)
有人知道一种Python式的方式来执行命令吗?在
listen
通知网络堆栈开始在后台对传入的连接请求进行排队。对accept
的每个调用都接受队列中的下一个请求。看起来你的子进程想连接回这个程序。听完后再打电话。在你已经得到了你的具体案例的有效答案。但是,如果您更喜欢一个更通用的解决方案来解决更一般的问题,那么几乎没有不同的方法可以实现这一点。在
让我们定义一个问题:我想调度一个任务,准备一些资源给工作线程,然后在主线程中等待资源准备就绪。资源的准备只进行一次。当然,仍然有一个有效的问题:为什么我们不能在一个线程中按顺序运行所有的东西?但是让我们把这看作是一个介绍多线程世界的练习。在
下面是一些基本的python代码:
当然,它并不像预期的那样工作,并且在输出的某个地方会有一条
ERROR
消息。但我们可以把问题改成:什么取代了WAIT HERE
?解决此类问题最明显也是最糟糕的方法是主动等待:
^{pr2}$尝试运行这段代码并观察(在Linux上使用
top
)CPU使用情况。你会注意到它在等待中长大。所以,请不要在现实生活中做这样的事情。在规定资源准备只进行一次。所以,工作线程可以准备数据,然后我们可以等待这个线程在主线程中完成。在这种情况下,这是我的首选解决方案。在
最后,使用一个完整的锁和条件变量方案。它需要更多的更改,因此完整的代码粘贴在这里:
如果您需要在一个线程中以循环方式准备资源(例如,一些数据),并在另一个线程中使用它,这将是一种合适的方法。请查找生产者-消费者模型。在
最后但并非最不重要。我为
global
变量使用了global
说明符,因为我很懒,而且这个例子是关于不同的东西的。但是,把它看作是一个糟糕的设计。变量只能在do_sth
和prepare_sth
线程之间共享。您可以使用args
和kwargs
方法的参数。在相关问题 更多 >
编程相关推荐