如何在多进程python程序中捕获Ctrl
+ C
,并正常退出所有进程,我需要在Unix和Windows上均可使用的解决方案。我尝试了以下方法:
import multiprocessing
import time
import signal
import sys
jobs = []
def worker():
signal.signal(signal.SIGINT, signal_handler)
while(True):
time.sleep(1.1234)
print "Working..."
def signal_handler(signal, frame):
print 'You pressed Ctrl+C!'
# for p in jobs:
# p.terminate()
sys.exit(0)
if __name__ == "__main__":
for i in range(50):
p = multiprocessing.Process(target=worker)
jobs.append(p)
p.start()
这是可行的,但我认为这不是正确的解决方案。
正确的方法来处理Ctrl+C
/SIGINT
用multiprocessing.Pool
是:
SIGINT
在Pool
创建流程之前,请忽略该流程。这样创建的子进程继承了SIGINT
处理程序。SIGINT
a之后,在父进程中还原原始处理程序Pool
。map_async
和apply_async
代替阻塞map
和apply
。把它放在一起:
#!/bin/env python
from __future__ import print_function
import multiprocessing
import os
import signal
import time
def run_worker(delay):
print("In a worker process", os.getpid())
time.sleep(delay)
def main():
print("Initializng 2 workers")
original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN)
pool = multiprocessing.Pool(2)
signal.signal(signal.SIGINT, original_sigint_handler)
try:
print("Starting 2 jobs of 5 seconds each")
res = pool.map_async(run_worker, [5, 5])
print("Waiting for results")
res.get(60) # Without the timeout this blocking call ignores all signals.
except KeyboardInterrupt:
print("Caught KeyboardInterrupt, terminating workers")
pool.terminate()
else:
print("Normal termination")
pool.close()
pool.join()
if __name__ == "__main__":
main()
正如@YakovShklarov指出的那样,在父进程中忽略信号和忽略信号之间存在时间窗口,在此期间信号可能会丢失。pthread_sigmask
在父进程中使用临时阻止信号的传递可以防止信号丢失,但是在Python-2中不可用。
Ctrl-C/SIGTERM/SIGINT似乎被tkinter忽略。通常情况下,它可以通过回调再次捕获。这似乎不起作用,所以我想我应该在另一个线程中运行tkinter,因为它的main循环()是一个无限循环和块。实际上,我也想这样做,以便在一个单独的线程中阅读stdin。即使在此之后,Ctrl-C仍然不会处理,直到我关闭窗口。这是我的MWE: 结果: 运行应用程序 终端中的Ctrl-C(什么都没发
问题内容: 我正在研究启动多个进程和数据库连接的python脚本。我不时地想用信号杀死脚本,我想进行一些清理。 在Perl中,我可以这样做: 如何在Python中做类似的事情? 问题答案: 用以下方式注册你的处理程序: 代码改编自此处。
在我的Java控制台应用程序中,我按下Ctrl C键并添加一个线程,使用Runtime.getRuntime(). addShutdownHook()执行优雅的关机 在这个线程中,我处理一些内部队列中的所有遗留工作,并优雅地退出我的应用程序,这通常是我想要的。 然而,有时应用程序可能会有需要一段时间(几分钟)才能处理的内部队列,如果是这样的话,我希望有一个选项可以再次按Ctrl C以强制退出应用程
问题内容: 我正在阅读出色的在线书籍http://nodebeginner.org/,并尝试了简单的代码 现在我不知道(而且我仍然不知道!)如何优雅地关闭node.js,所以我就去了。现在,每次我尝试运行时,都会收到以下错误消息。 因此,有两个问题: 1)如何正常关闭node.js? 2)如何修复我创建的混乱? 问题答案: 使用+ 优雅地退出节点进程 清理混乱取决于您的平台,但基本上,您需要找到运
我有一个程序,我在其中构建了一个ffmpeg命令字符串,以捕获通过gtk3 GUI输入的选项视频。一旦选择了所有选项,我就会生成一个带有ffmpeg命令字符串的进程。我添加了一个儿童手表来告诉我什么时候该过程已经完成。 使用命令行从终端执行ffmpeg,程序将提供一个选项,在终端输入一个“Q”,以提前结束ffmpeg过程。是否有任何方法可以发送一个“Q”到这个产生的进程,以优雅地结束FFMPEG?
问题内容: 是否可以在Java命令行应用程序中捕获+ 信号?我想在终止程序之前清理一些资源。 问题答案: 您可以将关闭挂钩连接到VM,只要VM关闭,该挂钩便会运行: Java虚拟机将响应以下两种事件而关闭: 当最后一个非守护程序线程退出时,或者调用exit(等效于System.exit)方法时,程序将正常退出,或者 响应于用户中断(例如键入+ )或系统范围的事件(例如用户注销或系统关闭)来终止虚拟