如果我错了,请纠正我。 目标:通过产生复制文件到另一个进程(因此实际复制不会“锁定”调用它的进程)。
cmd = ['cp', '/Users/username/Pictures/2Gb_ImageFile.tif', '/Volume/HugeNetworkDrive/VerySlow/Network/Connection/Destination.tif']
def copyWithSubprocess(cmd):
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
copyWithSubprocess(cmd)
答案 0 :(得分:1)
在Python中处理复杂异步进程的最简单方法是使用multiprocessing
库,该库专门用于支持此类任务,并且具有与threading
模块非常相似的接口(实际上)我编写的代码可以在多线程和多处理操作之间切换,主要是通过导入一个库或另一个库,但这需要对模块的哪些部分使用相当严格的限制。)
[编辑:删除了关于线程的虚假建议并使我的开场断言不那么夸张]
答案 1 :(得分:1)
Popen(cmd, stdout=PIPE, stderr=PIPE)
不会“锁定”您的父进程。
cmd
可能会停止运行。如果要丢弃子流程'输出,请使用DEVNULL
代替PIPE
:
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)
# ...
如果你想在不阻塞主线程的情况下处理输出,那么你可以使用几种方法:fcntl
,select
,命名管道与iocp,threads。后者是一种更便携的方式:
p = Popen(cmd, stdout=PIPE, stderr=PIPE, bufsize=-1)
bind(p.stdout, stdout_callback)
bind(p.stderr, stderr_callback)
# ...
其中bind()
函数:
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
在不阻塞主线程的情况下,您不需要外部进程来复制Python中的文件:
import shutil
from threading import Thread
Thread(target=shutil.copy, args=['source-file', 'destination']).start()
Python可以在I / O期间释放GIL,因此复制同时发生并与主线程并行发生。
您可以将它与使用多个进程的脚本进行比较:
import shutil
from multiprocessing import Process
Process(target=shutil.copy, args=['source-file', 'destination']).start()
如果您想在程序死亡时取消复制,请将thread_or_process.daemon
属性设置为True
。