我正在将一个应用程序从Python 2迁移到Python 3.该应用程序包含一个Python脚本,该脚本协调了几个C应用程序实例.python脚本 for each 应用程序打开一个套接字,然后将相应的文件描述符传递给C程序.这适用于Python 2.7的原始版本,但与Python 3.6或3.9不同.
我发现了一个变化:默认情况下,子进程不会继承stdin
、stdout
和stderr
之外的文件描述符(更多信息here)
我所做的是:
import socket
import os
import subprocess
sock = socket.socket()
sock.bind(('10.80.100.32',0))
sock
# Out[6]: <socket.socket fd=11, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('10.80.100.32', 36737)>
env = os.environ.copy()
env["LD_LIBRARY_PATH"] = env["LD_LIBRARY_PATH"] + ":%s" % os.getcwd()
p = subprocess.Popen(["./app", "--sockfd", "11"], close_fds = False, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.pid
# Out[10]: 393727
然后,我判断相应的进程:对于Python 2,要么它存在并且有一个服务器正在等待连接,要么对于Python 3,该进程已死亡.
我试图将文件描述符设置为可继承:
os.get_inheritable(11)
# Out[15]: False
os.set_inheritable(11, True)
然而,这没有帮助,应用程序仍然崩溃.
我还试图显式地将pass_fds = [11]
传递到Popen
,这也没有帮助.
如果我运行应用程序并让它自己创建套接字,那么它就可以正常工作,包括从Python脚本启动时.因此,在这一点上,我相当确定问题与从Python 2到Python 3的一些更改有关.
是否有其他可能对观察到的行为产生影响的变化?我还能做些什么呢?