<p><code>Popen(cmd, stdout=PIPE, stderr=PIPE)</code>不会“锁定”父进程。在</p>
<p><code>cmd</code>如果由于管道缓冲区满而生成足够的输出,则可能会自行暂停。如果要放弃子进程的输出,请使用<code>DEVNULL</code>而不是<code>PIPE</code>:</p>
<pre><code>import os
from subprocess import Popen, STDOUT
DEVNULL = open(os.devnull, 'wb') #NOTE: it is already defined in Python 3.3+
p = Popen(cmd, stdout=DEVNULL, stderr=STDOUT)
# ...
</code></pre>
<p>如果您想在不阻塞主线程的情况下处理输出,那么可以使用几种方法:<code>fcntl</code>,<code>select</code>,带iocp的命名管道,<a href="https://stackoverflow.com/q/375427/4279">threads</a>。后者是一种更便携的方式:</p>
^{pr2}$
<p>其中<code>bind()</code>函数:</p>
<pre><code>from contextlib import closing
from functools import partial
from threading import Thread
def bind(pipe, callback, chunksize=8192):
def consume():
with closing(pipe):
for chunk in iter(partial(pipe.read, chunksize), b''):
callback(chunk)
t = Thread(target=consume)
t.daemon = True
t.start()
return t
</code></pre>
<p>在不阻塞主线程的情况下,不需要外部进程在Python中复制文件:</p>
<pre><code>import shutil
from threading import Thread
Thread(target=shutil.copy, args=['source-file', 'destination']).start()
</code></pre>
<p>Python可以在I/O期间释放GIL,因此复制可以同时进行,也可以与主线程并行进行。在</p>
<p>可以将其与使用多个进程的脚本进行比较:</p>
<pre><code>import shutil
from multiprocessing import Process
Process(target=shutil.copy, args=['source-file', 'destination']).start()
</code></pre>
<p>如果您想在程序停止时取消复制,请将<code>thread_or_process.daemon</code>属性设置为<code>True</code>。在</p>