文件描述符的继承 - Python 3.4

Posted

技术标签:

【中文标题】文件描述符的继承 - Python 3.4【英文标题】:Inheritance of file descriptors - Python 3.4 【发布时间】:2015-05-16 14:50:27 【问题描述】:

https://docs.python.org/3.5/library/os.html#fd-inheritance 下关于“文件描述符的继承”的文档说:

“在 UNIX 上,不可继承的文件描述符在执行新程序时在子进程中关闭,其他文件描述符被继承。”

套接字的文档还说,“新创建的套接字是不可继承的。”

我刚刚使用以下代码对其进行了测试:

import socket, os

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('localhost', 9999))
sock.listen(512)
sock.settimeout(1)

print("Socket inheritable?: ".format(sock.get_inheritable()))

pid = os.fork()
if not pid: # child process
    print(sock)
else:
    pass

通过调用“sock.get_inheritable()”我得到 False,这意味着套接字是不可继承的。 但是子进程似乎继承了套接字描述符。

我错过了什么吗? 为什么会这样?

谢谢

更新:

这是在子进程中等待接受的“server.py”:

import socket, os, time

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('localhost', 9999))
sock.listen(512)
sock.setblocking(True)

print("Socket inheritable?: ".format(sock.get_inheritable()))

pid = os.fork()
if not pid: # child process
    sock, addr = sock.accept()
    data = sock.recv(100)
    print(data.decode())
else:
    while True:
        time.sleep(1)

“client.py”向套接字发送“Hello”:

import socket, time, select, sys

msg = "Hello".encode()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost',9999))
s.setblocking(1)
s.send(msg)
s.close()

启动 server.py 并运行“client.py”后,我在“server.py”的终端中看到“Hello”消息。

【问题讨论】:

我对此并不完全确定,但我认为继承仅适用于“在执行新程序时”,这意味着使用 os.fork 创建的子进程将继承文件描述符,但那些使用os.systemsubprocess 等创建的,不会继承文件描述符。 【参考方案1】:

不可继承意味着描述符已关闭,正如您在引用中所说的那样。这并不意味着 Python 中对 socket 对象的引用消失了。

更有意义的测试是尝试从条件的两个分支中的套接字读取。

【讨论】:

关闭fd有什么意义?套接字对象在子进程中是否仍然可用? 这就是重点——socket对象在子进程中不可用,只能在父进程中使用。 刚刚测试了一下,我可以在子进程的socket上完美接收数据。 @user2624744,如果您愿意,可以发布更新后的代码,在您的问题中显示新测试。

以上是关于文件描述符的继承 - Python 3.4的主要内容,如果未能解决你的问题,请参考以下文章

Python 3.4 GUI 单一可执行文件

Python 3.4 使用 time.sleep() 写入文件的问题

在 Python 3.4 中加载和读取具有多个 JSON 对象的 JSON 文件

Transient修饰符的使用

如何使用 python 3.4 创建一个独立的 exe

ubuntu python 3.4没有站点包库[重复]