<p>我要回答一个稍微不同的问题,因为这是我能找到的最接近的类似问题。在</p>
<p>我遇到了一个程序的问题,该程序监听端口并使用子流程.Popen(). 如果我正在执行的脚本在后台运行一个长时间运行的作业(通过),并且我终止了主程序,则长时间运行的作业将接管主程序的侦听端口。在</p>
<p>主程序:</p>
<pre><code>import BaseHTTPServer
from BaseHTTPServer import BaseHTTPRequestHandler
import subprocess
class RequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
proc = subprocess.Popen('start_long_proc.sh', shell=True)
stdout, stderr = proc.communicate(input)
self.send_response(200)
self.end_headers()
self.wfile.write('request served')
httpd = BaseHTTPServer.HTTPServer(('', 8000), RequestHandler)
httpd.serve_forever()
</code></pre>
<p>当httpd服务器接收到一个请求时,它将运行“start”long_工艺sh'. 脚本如下所示:</p>
^{pr2}$
<p>开始\u long_工艺sh立即返回,请求服务完成。现在问题来了:</p>
<p>如果我在<code>sleep</code>仍在运行时终止web服务器,<code>sleep</code>将接管侦听端口:</p>
<pre><code>$ netstat -pant | grep 0.0.0.0:8000
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 24809/sleep
</code></pre>
<p><strong>解决方案是在调用脚本时关闭除0、1和2(stdin、stdout、stderr)以外的所有文件描述符。Popen()为此提供了一个标志“close_fds”:</p>
<pre><code>proc = subprocess.Popen('start_long_proc.sh', shell=True, close_fds=True)
</code></pre>
<p>现在睡眠不再束缚监听端口:</p>
<p>$netstat-pant | grep 0.0.0.0:8000
美元</p>
<p>发生这种情况的原因是子进程从其父进程继承打开文件描述符。让我恼火的是它包括监听端口。我以前见过“close”选项,但认为它也关闭了STDIN、STDOUT和STDERR。但它没有,所以您仍然可以像正常一样与子进程通信。在</p>