python 2.7:如何在具有25个以上线程的程序中捕获键盘中断 [英] python 2.7: how to catch keyboard interrupt in program with more than 25 threads

查看:142
本文介绍了python 2.7:如何在具有25个以上线程的程序中捕获键盘中断的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在用户按下ctrl-C时停止我的程序. 以下答案建议捕获KeyboardInterrupt异常.

I want to stop my program when the user presses ctrl-C. The following answer suggests catching the KeyboardInterrupt exception.

python:如何在main时终止线程程序结束

有时可以.但是在下面的示例中,在我将线程数从25增加到30后,它停止工作.

Sometimes it works. But in the following example, it stops working after I increase the number of threads from 25 to 30.

import threading, sys, signal, os

stderr_lock = threading.Lock()

def Log(module, msg):
    with stderr_lock:
        sys.stderr.write("%s: %s\n" % (module, msg))

class My_Thread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        Log("Init", "Initing.")
        self.start()
    def run(self):
        try:
            while True:
                Log("Run", "Running.")
        except KeyboardInterrupt:
            os._exit(0)

for i in range(30):
    My_Thread()

# trap ctrl-C in main thread
try:
    while True:
        pass
except KeyboardInterrupt:
    os._exit(0)

与以下问题非常可疑地相似:

This has a very suspiciously similar feel to the following question:

Python 2.7中的线程安全信号API

在那种情况下,将线程数增加到87以上后,我无法捕获信号.

In that case, I was unable to catch signals after increasing the number of threads beyond 87.

推荐答案

您的代码实际上存在两个不同的问题,可以解决此问题.第一个是将您的线程划分为daemon个线程,以便它们在主线程退出时自动停止,第二个是您的try块不封装线程的创建和启动.

There are actually two different issues with your code that gives this behavior. The first is that your threads should be made into daemon threads, so that they automatically stops when the main thread exits, the second is that your try block does not encapsulate the thread creation and start-up.

创建多个线程时,线程创建不会在相当长的时间内完成(因为创建的线程和

When you create a number of threads, the thread creation won't be finished for quite a while (since it is continuously interrupted by the created threads and the GIL prevents them to run in parallel). Therefore, you send your KeyboardInterrupt before being set up to be handled. However, the KeyboardInterrupt will still kill the main thread (with a Traceback), but not the child threads.

因此,如果将代码修改为:

Thus, your code works if you modify it as:

import threading, sys, signal, os

stderr_lock = threading.Lock()

def Log(module, msg):
    with stderr_lock:
        sys.stderr.write("%s: %s\n" % (module, msg))

class My_Thread(threading.Thread):
    def __init__(self, value):
        threading.Thread.__init__(self)
        self.value = value
        Log("Init", "Initing %d." % self.value)
        self.daemon = True
        self.start()
    def run(self):
        while True:
            Log("Run", "Running %d." % self.value)

# trap ctrl-C in main thread
try:
    for i in range(1000):
        My_Thread(i)

    while True:
        pass
except KeyboardInterrupt:
    os._exit(0)

请注意,在当前示例中,并非严格要将线程设置为守护进程,但是对于应该在主程序结束时结束的线程,我认为这是一种好习惯.

Note, that making the threads into daemons is not strictly necessary in the current example, but I would consider that to be good practice for threads that are supposed to end when the main program ends.

这篇关于python 2.7:如何在具有25个以上线程的程序中捕获键盘中断的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆