Python 如何使用aiozmq/zmq正确关闭?
我在后端未运行时遇到此问题。Python 如何使用aiozmq/zmq正确关闭?,python,python-3.x,python-asyncio,pyzmq,Python,Python 3.x,Python Asyncio,Pyzmq,我在后端未运行时遇到此问题。 您可以在这里找到一个非常简单的演示来重现我的案例(如果您想节省一些测试时间,可以将超时时间减少到1): #/usr/bin/env蟒蛇3 导入线程 导入日志记录 导入异步 从aiozmq导入rpc logging.getLogger().setLevel(logging.DEBUG) 异步def go(): logging.debug('Go!') 客户端=无 尝试: client=等待rpc.connect\u rpc(connect=)tcp://127.0.0
您可以在这里找到一个非常简单的演示来重现我的案例(如果您想节省一些测试时间,可以将超时时间减少到1):
#/usr/bin/env蟒蛇3
导入线程
导入日志记录
导入异步
从aiozmq导入rpc
logging.getLogger().setLevel(logging.DEBUG)
异步def go():
logging.debug('Go!')
客户端=无
尝试:
client=等待rpc.connect\u rpc(connect=)tcp://127.0.0.1:5555,超时=5)
等待客户端。呼叫。远程(1,2)
例外情况除外,如e:
logging.exception(e)
最后:
如果客户端不是无:
client.close()
等待客户端。等待关闭()
logging.debug('done'))
loop=asyncio.get\u event\u loop()
循环。运行_直到_完成(go())
loop.close()
logging.debug(asyncio.Task.all_tasks())
logging.debug(threading.enumerate())
您会注意到两个coro(go
&我们等待的那个)都完成了,python只跟踪主线程
但您可以在顶部(htop
)中看到,您的脚本实际上运行了两个线程
- 1在
epoll\u等待(10,
- 1循环:
epoll_wait(13, [], 256, 168) = 0
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) = 3
fcntl(3, F_SETFD, FD_CLOEXEC) = 0
fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(5555), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
epoll_ctl(13, EPOLL_CTL_ADD, 3, {0, {u32=1275071824, u64=140476770422096}}) = 0
epoll_ctl(13, EPOLL_CTL_MOD, 3, {EPOLLOUT, {u32=1275071824, u64=140476770422096}}) = 0
epoll_wait(13, [{EPOLLOUT|EPOLLERR|EPOLLHUP, {u32=1275071824, u64=140476770422096}}], 256, -1) = 1
epoll_ctl(13, EPOLL_CTL_DEL, 3, 0x7fc34c000d54) = 0
getsockopt(3, SOL_SOCKET, SO_ERROR, [111], [4]) = 0
close(3) = 0
epoll_wait(13,[],256,168)=0
套接字(AF_INET、SOCK_STREAM、IPPROTO_TCP)=3
fcntl(3,F_SETFD,FD_CLOEXEC)=0
fcntl(3,F_GETFL)=0x2(标志O_RDWR)
fcntl(3,F_SETFL,O_RDWR | O_NONBLOCK)=0
连接(3,{sa_family=AF_INET,sin_port=htons(5555),sin_addr=INET_addr(“127.0.0.1”)},16)=-1 EINPROGRESS(操作正在进行)
epoll_ctl(13,epoll_ctl_ADD,3,{0,{u32=1275071824,u64=140476770422096}})=0
epoll-ctl(13,epoll-ctl-MOD,3,{EPOLLOUT,{u32=1275071824,u64=140476770422096}})=0
epoll_wait(13,[EPOLLOUT | EPOLLERR | EPOLLHUP,{u32=1275071824,u64=140476770422096}],256,-1)=1
epoll_ctl(13,epoll_ctl_DEL,3,0x7fc34c000d54)=0
getsockopt(3,SOL_套接字,SO_错误,[111],[4])=0
关闭(3)=0
我不是100%确定,但我认为我们收到的epollut | EPOLLERR | EPOLLHUP
是HUP=HangUp=connectiondenied
我在zmq库的某个地方找到了剩余的/不可见的线程
有人知道发生了什么事以及如何正确地阻止它吗?我也在github上发布了这篇文章,并得到了答案
这实际上是由于
解决方案只是在调用connect\u rpc
之后添加client.transport.setsockopt(zmq.LINGER,0)
在最后关闭的if
中添加loop.is_running()
也很有用,以防止在循环不再运行时尝试关闭套接字(例如,由于另一个异常)。我也将此作为github上的一个发布,并得到了答案
这实际上是由于
解决方案只是在调用connect\u rpc
之后添加client.transport.setsockopt(zmq.LINGER,0)
在的if
中添加loop.is_running()
也很有用,以防止在循环不再运行时尝试关闭套接字(例如,由于另一个异常)