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

Ric*_*ark 2 python sockets subprocess python-2.7

我有一个 Python2.7 脚本,它做了一些并行魔法,最后进入 Flask gui_loop。在某些时候,一个线程使用 subprocess.Popen 创建一个后台进程。这有效。

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

socket.error: [Errno 98] Address already in use
Run Code Online (Sandbox Code Playgroud)

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

root@test:/tmp# netstat -peanut | grep 5000
tcp        0      0 127.0.0.1:5000          0.0.0.0:*               LISTEN      1000       840210      21458/python    
Run Code Online (Sandbox Code Playgroud)

终止 Python 脚本后,socket 不会关闭,而是将其所有权传递给子进程:

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
Run Code Online (Sandbox Code Playgroud)

有没有办法解决?子进程(用 C 编写)没有在那个套接字上做任何事情,也不需要它。我可以以某种方式创建一个子进程而不将 gui 循环套接字资源传递给它吗?

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

电阻

mat*_*ata 5

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

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