【发布时间】:2017-10-05 16:55:30
【问题描述】:
Socket.close() 不会停止任何已经在该套接字上运行的阻塞 socket.accept() 调用。
我的 python 程序中有几个线程,它们只在已经关闭的 unix 域套接字上运行阻塞 socket.accept() 调用。 我想通过使 socket.accept() 调用停止或终止这些线程 引发异常。
我试图通过在程序中加载新代码而不停止程序来做到这一点。 因此,更改生成这些线程或关闭套接字的代码不是一种选择。
有什么办法吗?
这类似于https://stackoverflow.com/a/10090348/3084431,但这些解决方案不适用于我的代码:
- 这点不正确,关闭不会在接受时引发异常。 shutdown 可以,但是当线程关闭时就不能再调用了。
- 我无法再连接到此套接字。套接字已关闭。
- 带有接受调用的线程已经在运行,我无法更改它们。
- 同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
我需要的是在这段代码完成后可以运行的东西,它可以以某种方式停止接受者线程。
【问题讨论】:
-
普通套接字行为有什么问题?如果
accept“已经在运行”,则在技术上接受了一个连接在您停止接受新连接之前 - 所以一切正常。如果你想踢掉所有现有的客户,那就是你应该做的。 -
你永远无法完成这项工作。你的代码已经有一个严重的竞争条件——如果
sock.close()与accept的调用同时执行会发生什么? Python 的套接字对象不是线程安全的——当另一个线程访问它时,它不能在一个线程中修改其状态。绝对无法确保accept正在运行,而不是即将运行或准备阻止。所以这不能安全地完成,期间。 -
@ivan_pozdeev 没有客户端,它只是一个阻塞的
accept函数,它永远等待并阻止线程完成。 @DavidSchwartzsock.close实际上是在sock.accept运行时执行的。问题是套接字现在已关闭,但sock.accept仍在运行
标签: python multithreading sockets unix-socket