【发布时间】:2016-04-05 01:51:06
【问题描述】:
在类似 C/C++ 的语言中,明确关闭 zeromq 套接字是必须的,我明白这一点。但是在一些高级语言中,比如php和python,有垃圾回收机制,我需要显式关闭socket吗?
在 php 中,没有 ZMQSocket::close(),而在 python 中,pyzmq 的文档说 socket.close() 可以省略,因为它会在垃圾收集期间自动关闭。
所以我的问题是,我是否需要手动关闭它?...
【问题讨论】:
在类似 C/C++ 的语言中,明确关闭 zeromq 套接字是必须的,我明白这一点。但是在一些高级语言中,比如php和python,有垃圾回收机制,我需要显式关闭socket吗?
在 php 中,没有 ZMQSocket::close(),而在 python 中,pyzmq 的文档说 socket.close() 可以省略,因为它会在垃圾收集期间自动关闭。
所以我的问题是,我是否需要手动关闭它?...
【问题讨论】:
当您完成所有 I/O 资源时,关闭它们总是正确的。垃圾收集器最终会关闭它们。一旦最后一个引用超出范围,它可能会立即关闭它。它可能会在您的程序退出时关闭它。当您等待它这样做时,资源仍然处于打开状态,占用内存,消耗文件指针,并且通常会占用您的系统资源。对于一个小而短的程序来说,这可能不是什么大问题,但如果你的软件寿命很长或建立了很多连接,这会反过来伤害你。
答案是:视情况而定。如果您的系统依赖于套接字关闭,那么您更安全地明确关闭它们。如果您对在未来某个不确定的时间关闭套接字感到满意,您可以通过让垃圾收集器处理它来节省一点编码时间并稍微简化您的程序。
【讨论】:
当前文档状态,关闭套接字(或调用 Context.term() 不是必需的,因为它是通过垃圾收集自动完成的。
但是,pyzmq changelog states,从 14.3.0 版开始,这不是真的,因为 Python 3.4 中的更改不允许明智地做这样的事情。
我已经为此提交了一个问题Update docstrings about context.term() and socket.close() with regards to garbage collection。
【讨论】:
关闭你使用的资源被认为是一种很好的风格。
通常情况下,垃圾收集期间会关闭事物。但在调用__del__() 时,它是一个实现细节。在 CPython 中,您有引用计数,并且一旦不再使用对象就会被丢弃。 Jython 等其他实现可能会有所不同。
允许实现推迟垃圾收集或完全忽略它 - 只要没有收集仍然可访问的对象,垃圾收集的实现方式就是实现质量的问题。
在 2.5 或 2.6 中,引入了上下文管理器来解决这类问题。从那时起,以这种方式处理文件被认为是一种很好的风格:
with open(...) as f:
# do stuff with file object f
# now it is automatically closed.
我不知道 zeromq,但可能它也支持上下文管理器。
如果我通过命令行单行工作,我个人会很草率,但在完整的程序中往往相当严格。显式总比隐式好。
【讨论】:
你没有。在以下情况下,您可能会在 Python 中显式关闭或删除内容:
一般来说,甚至在 Python 中考虑这些事情都为时过早。
【讨论】: