python获取所有与套接字打开的文件描述符
我在一个基于Unix的操作系统上使用Flask和Flask自带的网络服务器。我是这样运行它的:
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()
当我停止Flask应用时,我重启的其他服务会开始监听8000端口。这是因为Flask打开的文件描述符被子进程继承了。为了防止这个问题,我想获取所有的套接字文件描述符。我该怎么做呢?
3 个回答
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)
1
在这种情况下,调用 Popen 时应该设置 close_fds = True。
3
要解决这个问题,可以使用gc模块来获取所有创建的对象。在创建并绑定套接字之后,你可以运行这段代码来获取所有的套接字对象;
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)
这段代码可以防止套接字的文件描述符被继承。