2017-08-04 6 views
1

をキャッチしていない私は、クリーンな方法でPythonのスレッドを殺害について、ここで複数のスレッドを見てきましたが、私はもっと根本的な問題を抱えていると思います。私はCtrl-Cをキーボード割り込みを気づくために、メインスレッドの希望、そしてそこから、私は他のスレッド(t1t2)の終了を扱うことができるメインスレッドはKeyboardInterrupt

t1 = threading.Thread(target=method1, args=(args1,)) 
t1.daemon = True 

t2 = threading.Thread(target=method2, args=(args2,)) 
t2.daemon = True 
t1.start() 
t2.start() 

while True: 
    time.sleep(1) 

:私はこのようになりますいくつかのコードを持っていると仮定文脈を考慮して適切である。しかし、私が何をしても、私はメインスレッドにKeyboardInterruptをキャッチすることはできません。

try: 
    while True: time.sleep(100) 
except KeyboardInterrupt: 
    print "Quitting!" 

またはこのような何か:私はこのような何か試してみた

threads = [] 
threads.append(t1) 
threads.append(t2) 
while len(threads) > 0: 
    try: 
     threads = [t for t in threads if t is not None and t.isAlive()] 
     time.sleep(1) 
    except: 
     print "Ctrl - C received, kiling" 
     for t in threads: 
      t.kill_received = True 

をしかし、これらのどれも、これだけの表示、例外ハンドラ内のメッセージを印刷しない:

Exception in thread Thread-3: 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner 
    self.run() 
    File "/usr/local/lib/python2.7/dist-packages/audioread/gstdec.py", line 149, in run 
    self.loop.run() 
    File "/usr/lib/python2.7/dist-packages/gi/overrides/GLib.py", line 576, in run 
    raise KeyboardInterrupt 
KeyboardInterrupt 
をここ

主な問題は、最終的には、私もそれに対処するために持っている(安全t1t2を殺すためにどのようにではありません)、なぜメインスレッドはKeyboardInterruptをキャッチしていないのですか?

編集:私は例を書いてきたように、私はすでにのtry-除くブロック内のwhileループで寝関与アプローチを試みました。他のアイデア?

+0

これは、私がthreading.Thread' 'サブクラス化しようとしたためCPythonのソースからコードをコピーした非常に神秘的です'run()'メソッドは 'try/finally'メソッドを持っています。私は例外に '例外:'を追加しましたが、 'KeyboardInterrupt'が発生したときには決して起動しません。少し深い魔法が続くはずです。私はスレッドがデモニックであるという事実と関係があるかもしれないと思います。 – martineau

+0

それは価値があるため、デーモンの属性をFalseに設定して試してみました。役に立たない。 – kaajaa328

+0

[is-there-any-way-to-kill-a-thread-]について読む(https://stackoverflow.com/questions/323972/is-there-any-way-to-kill-a-thread- in-python)、[keyboardinterrupt-in-multithreading](https://stackoverflow.com/questions/43721150/python-keyboardinterrupt-in-multithreading)、[keyboardinterrupt](https://stackoverflow.com/questions/4136632/) CTRL-CIE-keyboardinterrupt・ツー・キル・スレッド型のpython)の – stovfl

答えて

1

次のように動作します。 Threadサブクラスでtry...exceptがトリガされることはありませんにもかかわらず、メインスレッドKeyboardInterrupt秒をキャッチすることができます。私はメッセージを印刷するためにexcept BaseException as exc:を添加する

MyThreadサブクラスのrun()メソッドのコードは既にtry/finallyを含有Thread.run()方法についてはCPython 2.7源が何であるかの修正版です...どんなタイプのものが起こったとき。

import threading 
import time 

def method1(args): 
    print('method1() running') 
    while True: 
     time.sleep(.001) 

def method2(args): 
    print('method2() running') 
    while True: 
     time.sleep(.01) 


class MyThread(threading.Thread): 
    def __init__(self, *args, **kwargs): 
     super(MyThread, self).__init__(*args, **kwargs) 

    def run(self): 
     """ Method representing the thread's activity. 

     You may override this method in a subclass. The standard run() method 
     invokes the callable object passed to the object's constructor as the 
     target argument, if any, with sequential and keyword arguments taken 
     from the args and kwargs arguments, respectively. 
     """ 
     try: 
      print('in MyThread.run()\n') 
      if self._Thread__target: 
       self._Thread__target(*self._Thread__args, **self._Thread__kwargs) 
     except BaseException as exc: 
      print('reraising Exception {}'.format(exc)) 
      raise typeof(exc)(str(exc)) 
     finally: 
      # Avoid a refcycle if the thread is running a function with 
      # an argument that has a member that points to the thread. 
      del self._Thread__target, self._Thread__args, self._Thread__kwargs 
      print('exiting') 

args1 = 1 
t1 = MyThread(target=method1, args=(args1,)) 
t1.daemon = True 

args2 = 2 
t2 = MyThread(target=method2, args=(args2,)) 
t2.daemon = True 
t1.start() 
t2.start() 

try: 
    while True: 
     time.sleep(1) 
except BaseException as exc: 
    print('exception "{}" occurred'.format(type(exc))) 
    quit() 

コンソール出力(Iはmethod1() runningが登場した直後にCtrl-Cを入力):

> python not-catching-keyboardinterrupt.py 
in MyThread.run() 
in MyThread.run() 

method2() running 

method1() running 
exception "<type 'exceptions.KeyboardInterrupt'>" occurred 
関連する問題