我在基于unix的操作系统上使用flask和flask的内部Web服务器。我像那样运行它;
APP.run(host='', port=8000, threaded=True, debug=False)
我在我的代码中重启一些服务,如
for service in ACTIVE_SERVICES:
command = "/etc/init.d/%s restart" % service
# stdout and stderr are string which output of command
stdout, stderr = Popen(command, stdout=PIPE, stderr=PIPE,shell=True).communicate()
当我停止使用烧瓶应用程序时,我重启的其他服务开始监听8000端口。它是由子进程继承的烧瓶打开的文件描述符引起的。为了防止这个问题,我尝试访问套接字的所有文件描述符。怎么办?
答案 0 :(得分:2)
为解决此问题,gc可用于获取所有创建对象。在创建并绑定套接字之后,您可以运行此代码并获取所有socketobjects;
for sock in filter(lambda x: type(x) == socket._socketobject, gc.get_objects()):
fd = sock.fileno()
old_flags = fcntl.fcntl(fd, fcntl.F_GETFD)
fcntl.fcntl(fd, fcntl.F_SETFD, old_flags | fcntl.FD_CLOEXEC)
此代码阻止继承套接字的文件描述符。
答案 1 :(得分:1)
在这种情况下,应该用close_fds = True调用Popen。
答案 2 :(得分:0)
针对python3.8的完整解决方案
def _run_on_start(a_string):
import socket, fcntl
for sock in filter(lambda x: type(x) == socket.socket, gc.get_objects()):
fd = sock.fileno()
old_flags = fcntl.fcntl(fd, fcntl.F_GETFD)
fcntl.fcntl(fd, fcntl.F_SETFD, old_flags | fcntl.FD_CLOEXEC)
@app.before_first_request(_run_on_start)