运行进程并在不等待的情况下退出
在Windows下使用Python时,我想在一个单独的进程中运行一些代码。而且我不想让父进程等着它结束。我试过这样做:
from multiprocessing import Process
from time import sleep
def count_sheeps(number):
"""Count all them sheeps."""
for sheep in range(number):
sleep(1)
if __name__ == "__main__":
p = Process(target=count_sheeps, args=(5,))
p.start()
print("Let's just forget about it and quit here and now.")
exit()
这段代码可以启动子进程并继续执行。但是,当父进程到达结束时,它还是会等着子进程退出。
有没有办法让父进程在子进程运行时就直接退出呢?当然,我可以使用subprocess.Popen
来启动一个新的Python解释器,并把羊数的代码作为一个单独的脚本传给它。
不过,Python有一个专门处理进程的模块,我想利用这个模块,而不是直接操作操作系统。而且,如果同样的代码能在所有支持Python的地方都能运行,那就太好了,而不仅仅是在Windows上。
6 个回答
你可以通过设置 p.daemon = True
来将这个进程声明为守护进程。正如这个链接所说:“这个标志的意思是,当只剩下守护线程时,整个Python程序会退出。”
from multiprocessing import Process
from time import sleep
def count_sheeps(number):
"""Count all them sheeps."""
for sheep in range(number):
sleep(1)
if __name__ == "__main__":
p = Process(target=count_sheeps, args=(5,))
p.daemon = True
p.start()
print("Let's just forget about it and quit here and now.")
exit()
在Linux系统下,你可以使用fork
这个命令来创建一个新的进程,但在Windows上这个方法不太管用。我觉得最简单的办法是运行一个新的Python进程。你可以把你的count_sheeps
函数放在一个单独的文件里,然后用Popen('python count_sheeps.py')
来启动这个文件。
使用 subprocess
模块,因为其他控制子进程的方法(比如 os.system、os.spawn*、os.popen*、popen2.、commands.)都在逐渐被淘汰。
from subprocess import Popen
Popen( [ "foo.exe", "arg1", "arg2", "arg3" )
查看 Python 文档,特别是 P_NOWAIT 的例子。
你需要在子进程中启动一个新的 Python 解释器,所以上面的 "foo.exe" 很可能会变成 "python.exe"。
编辑:
我刚刚查看了多进程模块的文档:
join_thread()
:用于连接后台线程。这个方法只能在调用了 close() 之后使用。它会阻塞,直到后台线程退出,确保缓冲区中的所有数据都已经写入管道。默认情况下,如果一个进程不是队列的创建者,那么在退出时它会尝试连接队列的后台线程。这个进程可以调用
cancel_join_thread()
来让join_thread()
不执行任何操作。
cancel_join_thread()
:防止join_thread()
阻塞。特别是,这可以防止后台线程在进程退出时被自动连接——参见join_thread()
。
看起来你应该可以调用 cancel_join_thread()
来实现你想要的效果。我之前从未使用过这个方法(直到刚才才知道它的存在!),所以如果你试过后有效,请务必告诉我们。