Python subprocess.Popen() - 子进程导致套接字保持打开状态

Python subprocess.Popen() - subprocess causes sockets to remain open

我有一个 Python2.7 脚本,它执行一些并行魔法并最终进入 Flask gui_loop。在某个时刻,一个线程创建了一个后台进程 subprocess.Popen。这行得通。

当我的脚本退出并且子进程仍在 运行ning 时,我无法再次 运行 我的脚本,因为 flask gui_loop 失败并显示:

socket.error: [Errno 98] Address already in use

使用 netstat -peanut 我可以看到当 python 脚本退出时套接字的所有权转移到子进程。这是 python 脚本和子进程都是 运行ning:

时的样子
root@test:/tmp# netstat -peanut | grep 5000
tcp        0      0 127.0.0.1:5000          0.0.0.0:*               LISTEN      1000       840210      21458/python    

终止Python脚本后,套接字没有关闭但其所有权被传递给子进程:

root@test:~/PycharmProjects/foo/gui# netstat -peanut | grep 5000
tcp        0      0 127.0.0.1:5000          0.0.0.0:*               LISTEN      1000       763103      19559/my-subprocess

有什么办法解决这个问题吗?子进程(用 C 语言编写)没有在该套接字上执行任何操作,也不需要它。我能以某种方式创建一个子进程而不将 gui 循环套接字资源传递给它吗?

我当然可以终止该过程,但这并不理想,因为这样做的目的是围绕一些计算构建一个简单的 gui,并且如果 gui 脚本恰好退出则不会丢失进度。如果我可以启动 gui 脚本并再次 运行ning,我将有一种机制来重新连接到子进程。

R

您可以尝试使用 with 语句。这里有一些文档:

http://preshing.com/20110920/the-python-with-statement-by-example/
https://www.python.org/dev/peps/pep-0343/

这会 open/close 为您清理。

您应该在创建子进程时使用close_fds=True,这将导致在子进程中关闭所有文件描述符(以及因此打开的套接字)(stdin/stdout/stderr除外)。

在较新的版本中 (python 3.2+) close_fds 已经默认为 True,因为在大多数情况下您不想继承子进程中所有打开的文件描述符, 但在 python2.7 中您仍然需要明确指定它。