【问题标题】:Python : http.server.HTTPServer : How to close ALL opened files?Python:http.server.HTTPServer:如何关闭所有打开的文件?
【发布时间】:2018-08-10 01:48:53
【问题描述】:

所以基本上,我正在 Python 3 中创建一个 HTTP webhooks 服务器,并希望添加一个重启功能,因为 shell 访问在它将运行的服务器上非常有限。

我之前在 Stack Overflow 的某个地方发现了这个 sn-p:

def restart_program():
    """Restarts the current program, with file objects and descriptors
       cleanup
    """

    try:
        p = psutil.Process(os.getpid())
        fds = p.open_files() + p.connections()
        print (fds)
        for handler in fds:
            os.close(handler.fd)
    except Exception as e:
        logging.error(e)

    python = sys.executable
    os.execl(python, python, *sys.argv)

在大多数情况下,它可以工作,但我想确保所以我用lsof 运行了一些测试,发现每次我重新启动服务器时,都会在 open 列表中添加两行(文件)文件:

python3 13923 darwin    5u  systm 0x18cd0c0bebdcbfd7        0t0            [ctl com.apple.netsrc id 9 unit 36]
python3 13923 darwin    6u   unix 0x18cd0c0beb8fc95f        0t0            ->0x18cd0c0beb8fbcdf

(每次重启时地址不同)

这些仅在我启动 httpd = ThreadingSimpleServer((host, port), Handler) 时出现。但即使在我致电httpd.server_close() 之后,这些打开的文件仍然存在,而 psutil 似乎找不到它们。

这并不是真正需要的功能。如果这被证明开销太大,我可以放弃它,但现在我只对我的代码为什么不起作用以及我自己的理智的解决方案感兴趣。

提前致谢!

更新

p.connections() 更改为p.connections(kind='all') 得到unix 类型fd。仍然不确定如何关闭 systm 类型 fd。原来unix fd 与 DNS 有关...

更新

好吧,看起来我找到了解决方案,尽管它可能很混乱。

class MyFileHandler(object):
    """docstring for MyFileHandler."""
    def __init__(self, fd):
        super(MyFileHandler, self).__init__()
        self.fd = fd

def get_open_systm_files(pid=os.getpid()):
    proc = subprocess.Popen(['lsof', '-p', str(pid)], stdout=subprocess.PIPE)
    return [MyFileHandler(int(str(l).split(' ')[6][:-1])) for l in proc.stdout.readlines() if b'systm' in l]

def restart_program():
    """Restarts the current program, with file objects and descriptors
       cleanup
    """

    try:
        p = psutil.Process(os.getpid())
        fds = p.open_files() + p.connections()
        print (fds)
        for handler in fds:
            os.close(handler.fd)
    except Exception as e:
        logging.error(e)

    python = sys.executable
    os.execl(python, python, *sys.argv)

它不漂亮,但它有效。

如果有人能对实际情况/正在发生的事情有所了解,我非常想知道。

【问题讨论】:

    标签: python unix lsof python-3.7 basehttpserver


    【解决方案1】:

    嗯,这看起来像是一种非常骇人听闻的方式来重新启动进程,而且总的来说是个坏主意。你的用例是什么?为什么要重新启动一个进程?无论您的动机如何,在这种意义上与流程交互的通常方式是通过信号。我不知道专门设计用于重新启动进程的信号。您通常想要做的是终止它(SIGTERM),并且可能有诸如 systemd 或 zdaemon 之类的东西会自动重新启动它。您甚至可以编写一个信号处理程序来在 SIGTERM 上执行清理功能,而 that 是进行清理的正确方法。不过,您通常不想重新启动进程,更不用说从应用程序本身进行了。这看起来像是麻烦的秘诀。

    【讨论】:

    • 是的,这就是我的感觉,但是当我用谷歌搜索“如何重新启动 python 程序”时,我发现了。我每分钟都会有一个 cron 作业检查它,所以我想我可以让它重新启动脚本。
    • 如果你想要一个纯 Python CLI 工具,你可以看看“zdaemon”。
    猜你喜欢
    • 2012-02-17
    • 2014-08-20
    • 2021-01-12
    • 2010-11-21
    • 2021-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-25
    相关资源
    最近更新 更多