kill socket.accept() 在关闭的 unix 套接字上调用
kill socket.accept() call on closed unix socket
Socket.close() 不会停止任何已在该套接字上 运行ning 的阻塞 socket.accept() 调用。
我的 python 程序中有几个线程,只有 运行 对已关闭的 unix 域套接字的阻塞 socket.accept() 调用。
我想通过使 socket.accept() 调用停止或
引发异常。
我试图通过在程序中加载新代码而不停止程序来做到这一点。
因此,更改生成这些线程或关闭套接字的代码不是一种选择。
有什么办法吗?
这类似于 ,但这些解决方案不适用于我的代码:
- 这一点是不正确的,关闭不会在接受时引发异常。 shutdown 可以,但是当线程关闭时就不能再调用了。
- 我无法再连接到这个套接字。套接字已关闭。
- 带有 accept 调用的线程已经 运行ning,我无法更改它们。
- 同 3
为了澄清,我写了一些有这个问题的示例代码。
此代码适用于 python 2 和 python 3.
import socket
import threading
import time
address = "./socket.sock"
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.bind(address)
sock.listen(5)
def accept():
print(sock.accept())
t = threading.Thread(target=accept, name="acceptorthread")
t.start()
sock.close()
time.sleep(0.5) # give the thread some time to register the closing
print(threading.enumerate()) # the acceptorthread will still be running
我需要的是在这段代码完成后我可以运行 以某种方式停止接受器线程的东西。
内核中没有机制通知每个侦听器套接字已关闭。你必须自己写点东西。一个简单的解决方案是在套接字上使用超时:
sock.settimeout(1)
def accept():
while True:
try:
print(sock.accept())
except socket.timeout:
continue
break
现在,当您关闭套接字时,对 .accept()
的下一次调用(超时后)将抛出 "bad descriptor" 异常。
还要记住 Python 中的套接字 api 不是线程安全的。建议在多线程环境中使用锁(或其他同步方法)包装每个套接字调用。
更高级(和高效)的方法是使用 select call 包裹您的套接字。请注意,套接字不必处于非阻塞模式即可使用它。
Therefore, changing the code that spawned these threads or that closed the sockets is not an option.
如果是这样,那你就完蛋了。不更改线程中的代码 运行 是不可能实现的。这就像问 "how can I fix my broken car without modifying the car"。不会发生的,伙计。
您应该只在某个 selectors
给出 "readable" 结果的套接字上调用 .accept()
。那么,accept不需要被打断。
但是在虚假唤醒的情况下,无论如何你都应该让监听套接字处于 O_NONBLOCK
模式。
Socket.close() 不会停止任何已在该套接字上 运行ning 的阻塞 socket.accept() 调用。
我的 python 程序中有几个线程,只有 运行 对已关闭的 unix 域套接字的阻塞 socket.accept() 调用。 我想通过使 socket.accept() 调用停止或 引发异常。
我试图通过在程序中加载新代码而不停止程序来做到这一点。 因此,更改生成这些线程或关闭套接字的代码不是一种选择。
有什么办法吗?
这类似于 ,但这些解决方案不适用于我的代码:
- 这一点是不正确的,关闭不会在接受时引发异常。 shutdown 可以,但是当线程关闭时就不能再调用了。
- 我无法再连接到这个套接字。套接字已关闭。
- 带有 accept 调用的线程已经 运行ning,我无法更改它们。
- 同 3
为了澄清,我写了一些有这个问题的示例代码。 此代码适用于 python 2 和 python 3.
import socket
import threading
import time
address = "./socket.sock"
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.bind(address)
sock.listen(5)
def accept():
print(sock.accept())
t = threading.Thread(target=accept, name="acceptorthread")
t.start()
sock.close()
time.sleep(0.5) # give the thread some time to register the closing
print(threading.enumerate()) # the acceptorthread will still be running
我需要的是在这段代码完成后我可以运行 以某种方式停止接受器线程的东西。
内核中没有机制通知每个侦听器套接字已关闭。你必须自己写点东西。一个简单的解决方案是在套接字上使用超时:
sock.settimeout(1)
def accept():
while True:
try:
print(sock.accept())
except socket.timeout:
continue
break
现在,当您关闭套接字时,对 .accept()
的下一次调用(超时后)将抛出 "bad descriptor" 异常。
还要记住 Python 中的套接字 api 不是线程安全的。建议在多线程环境中使用锁(或其他同步方法)包装每个套接字调用。
更高级(和高效)的方法是使用 select call 包裹您的套接字。请注意,套接字不必处于非阻塞模式即可使用它。
Therefore, changing the code that spawned these threads or that closed the sockets is not an option.
如果是这样,那你就完蛋了。不更改线程中的代码 运行 是不可能实现的。这就像问 "how can I fix my broken car without modifying the car"。不会发生的,伙计。
您应该只在某个 selectors
给出 "readable" 结果的套接字上调用 .accept()
。那么,accept不需要被打断。
但是在虚假唤醒的情况下,无论如何你都应该让监听套接字处于 O_NONBLOCK
模式。