[在使用 PyVirtualDisplay 时] 如何避免挂起 Xvfb 进程?

Posted

技术标签:

【中文标题】[在使用 PyVirtualDisplay 时] 如何避免挂起 Xvfb 进程?【英文标题】:How to avoid hanging Xvfb processes [while using PyVirtualDisplay]? 【发布时间】:2013-08-30 20:30:09 【问题描述】:

尝试找出在使用 PyVirtualDisplay 时如何避免在我们的 Python 应用程序中挂起 Xvfb 进程。根本问题是调用display.stop()(见下面的代码示例)似乎没有正确关闭Xvfb进程。

PyVirtualDisplay 使用非常简单:

from pyvirtualdisplay import Display

display = Display(backend='xvfb')
display.start()

... # Some stuff happens here

display.stop()

现在,Display 类稍作修改,以防止 Xvfb 使用 TCP 端口:基本上,将-nolisten tcp 添加到正在执行的命令中。修改是通过覆盖适当的 XfvbDisplay 类的 _cmd 属性来完成的:

@property
def _cmd(self):
    cmd = [PROGRAM,
           dict(black='-br', white='-wr')[self.bgcolor],
           '-screen',
           str(self.screen),
           'x'.join(map(str, list(self.size) + [self.color_depth])),
           self.new_display_var,
           '-nolisten',
           'tcp'
           ]
    return cmd

在这种情况下结束 Xvfb 进程的正确方法是什么,以便它们被终止并且不会逗留?

非常感谢!

【问题讨论】:

假设 pyvirtualdisplay 使用subprocess.Popen,您可以在这些对象上调用终止。如果您无法访问这些,那么您可以尝试在所有子进程上使用os.kill。 【参考方案1】:

您的显示,因为它继承自 EasyProcess,将在 display.popen 处具有一个 popen 属性。如果 EasyProcess 无法正常工作,您可以使用它来终止。

所以,你可以这样做:

display.popen.terminate()

display.popen.kill()

【讨论】:

谢谢。如果我无法再访问显示对象会怎样?有没有比使用操作系统调用更好的kill 方法? 实际上,这也是它在幕后所做的事情。答案是否定的,不是真的。 os.kill 实际上相当不错。这是一个不错的界面,您可以轻松地处理异常。【参考方案2】:

The answer by Jordan 对我不起作用。这有效:

display.sendstop()

【讨论】:

以上是关于[在使用 PyVirtualDisplay 时] 如何避免挂起 Xvfb 进程?的主要内容,如果未能解决你的问题,请参考以下文章

selenium在远程服务器上的虚拟显示

在JENKINS上部署selenium+python环境遇到的坑

为啥在使用自适应查询执行时要使用广播时火花洗牌

EF 和 [JsonIgnore]:为啥我在使用现有类型时得到空字典,但在使用匿名类型时却没有?

在 C++ 程序上使用加载时或运行时动态链接时,如何在编译时解析引用?

在使用 jupyter notebook 时如何在 pandas 中使用 Dataframe 时查看完整数据? [复制]