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 中您仍然需要明确指定它。
我有一个 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 中您仍然需要明确指定它。