我发现this文章解释了如何使用ctr + c杀死正在运行的多处理代码。以下代码完全正常工作(可以使用ctrl + c终止它):
#!/usr/bin/env python
# Copyright (c) 2011 John Reese
# Licensed under the MIT License
import multiprocessing
import os
import signal
import time
def init_worker():
signal.signal(signal.SIGINT, signal.SIG_IGN)
def run_worker():
time.sleep(15)
def main():
print "Initializng 5 workers"
pool = multiprocessing.Pool(5, init_worker)
print "Starting 3 jobs of 15 seconds each"
for i in range(3):
pool.apply_async(run_worker)
try:
print "Waiting 10 seconds"
time.sleep(10)
except KeyboardInterrupt:
print "Caught KeyboardInterrupt, terminating workers"
pool.terminate()
pool.join()
else:
print "Quitting normally"
pool.close()
pool.join()
if __name__ == "__main__":
main()
问题是我使用多处理模块的不同功能。我不知道它们与以前的方法有什么不同,它只适用于我(除了这个例子不能使用ctrl + c终止它)。以下是我根据上述版本尝试修改的代码(以前版本没有用于在ctrl + c命中时打印回溯的信号处理):
#!/usr/bin/env python
from time import sleep
import signal
from multiprocessing import Pool
from multiprocessing import cpu_count
def init_worker(n):
signal.signal(signal.SIGINT, signal.SIG_IGN)
sleep(.5)
print "n = %d" % n
results_sent_back_to_parent = n * n
return results_sent_back_to_parent
if __name__ == '__main__':
try:
p = Pool(processes = cpu_count())
results = p.map(init_worker, range(50), chunksize = 10)
except KeyboardInterrupt:
pool.terminate()
pool.join()
print(results)
问题:
pool.apply_async
和另一个map
)?修改
回复@ user2386841
我在signal.signal(signal.SIGINT, signal.SIG_IGN)
评论了init_worker
并试图在if __name__ == '__main__':
之后添加,但是ID没有用,当我在{{1}中添加它作为最后一行时也一样阻止
回复@ThomasWagenaar
它的行为完全相同(我还尝试过如上所述的信号处理程序的各种位置);尽管点击了try:
,但数字仍在打印,唯一可能的方法就是使用ctr+c
将其发送到后台,然后使用ctrl+z
答案 0 :(得分:3)
我用这个简单的函数解决了这个问题:
rescue
我把它附在我的游泳池上:
import os
import psutil
import signal
parent_id = os.getpid()
def worker_init():
def sig_int(signal_num, frame):
print('signal: %s' % signal_num)
parent = psutil.Process(parent_id)
for child in parent.children():
if child.pid != os.getpid():
print("killing child: %s" % child.pid)
child.kill()
print("killing parent: %s" % parent_id)
parent.kill()
print("suicide: %s" % os.getpid())
psutil.Process(os.getpid()).kill()
signal.signal(signal.SIGINT, sig_int)
ctrl ^ c之后的结果是:
Pool(3, worker_init)
一切都会退出
答案 1 :(得分:1)
旧线程,但这些示例表现不同的原因是由于众所周知的Python错误(http://bugs.python.org/issue8296,也在this StackOverflow answer中解释)。
你应该完全阅读其他答案以获得完整的想法,但简而言之,问题是底层threading.Condition.wait()
调用的行为会有所不同,具体取决于它是否超时。 map()
不使用超时,但apply_async()
显然确实利用了此超时参数,并且仅当该基础wait()
调用超时时才会正确中断。
您应该能够重构代码以使用the Pool docs中指定的异步方法之一。