61

私はこの単純なコードを実行しています:

import threading, time

class reqthread(threading.Thread):    
    def run(self):
        for i in range(0, 10):
            time.sleep(1)
            print('.')

try:
    thread = reqthread()
    thread.start()
except (KeyboardInterrupt, SystemExit):
    print('\n! Received keyboard interrupt, quitting threads.\n')

しかし、私がそれを実行すると、それは印刷されます

$ python prova.py
.
.
^C.
.
.
.
.
.
.
.
Exception KeyboardInterrupt in <module 'threading' from '/usr/lib/python2.6/threading.pyc'> ignored

実際、Pythonスレッドは私のCtrl+Cキーボード割り込みを無視し、出力しませんReceived Keyboard Interrupt。なんで?このコードの何が問題になっていますか?

4

5 に答える 5

72

試す

try:
  thread=reqthread()
  thread.daemon=True
  thread.start()
  while True: time.sleep(100)
except (KeyboardInterrupt, SystemExit):
  print '\n! Received keyboard interrupt, quitting threads.\n'

を呼び出さないtime.sleepと、メインプロセスがブロックから飛び出すのがtry...except早すぎるため、KeyboardInterruptがキャッチされません。私の最初の考えはを使用することでしたが、それが終了thread.joinするまでメインプロセス(KeyboardInterruptを無視)をブロックしているようです。thread

thread.daemon=Trueメインプロセスが終了すると、スレッドが終了します。

于 2010-09-24T14:51:04.303 に答える
13

コメントで推奨され いる変更を要約すると、次のことが私にとってうまく機能します。

try:
  thread = reqthread()
  thread.start()
  while thread.isAlive(): 
    thread.join(1)  # not sure if there is an appreciable cost to this.
except (KeyboardInterrupt, SystemExit):
  print '\n! Received keyboard interrupt, quitting threads.\n'
  sys.exit()
于 2014-05-01T17:30:18.883 に答える
7

ubuntuのソリューションを少し変更しました。

Ericが提案したようにtread.daemon=Trueを削除し、スリープループをsignal.pause()に置き換えます。

import signal
try:
  thread=reqthread()
  thread.start()
  signal.pause() # instead of: while True: time.sleep(100)
except (KeyboardInterrupt, SystemExit):
  print '\n! Received keyboard interrupt, quitting threads.\n'
于 2016-02-26T08:36:28.773 に答える
0

Thread.join()私の(ハッキーな)解決策は、次のようにモンキーパッチを適用することです。

def initThreadJoinHack():
  import threading, thread
  mainThread = threading.currentThread()
  assert isinstance(mainThread, threading._MainThread)
  mainThreadId = thread.get_ident()
  join_orig = threading.Thread.join
  def join_hacked(threadObj, timeout=None):
    """
    :type threadObj: threading.Thread
    :type timeout: float|None
    """
    if timeout is None and thread.get_ident() == mainThreadId:
      # This is a HACK for Thread.join() if we are in the main thread.
      # In that case, a Thread.join(timeout=None) would hang and even not respond to signals
      # because signals will get delivered to other threads and Python would forward
      # them for delayed handling to the main thread which hangs.
      # See CPython signalmodule.c.
      # Currently the best solution I can think of:
      while threadObj.isAlive():
        join_orig(threadObj, timeout=0.1)
    else:
      # In all other cases, we can use the original.
      join_orig(threadObj, timeout=timeout)
  threading.Thread.join = join_hacked
于 2015-03-06T13:27:34.347 に答える
0

try ... exceptを各スレッドに入れて、それsignal.pause()実際 main()に使ってみてください。

ただし、インポートロックには注意してください。これが、Pythonがデフォルトでctrl-Cを解決しない理由だと思います。

于 2017-09-21T23:39:20.013 に答える