2017-12-29 16 views
1

入力待ちのスレッドがありますが、入力がない場合はプログラムを終了する必要があります。どうすればプログラムを終了できますか?この例では、exitはキーボードのCtrl + Cキーでトリガーする必要がありますが、タイムアウトや他のイベントを経由してこの操作を行うこともできます。終了プログラムがsys.stdin.readlineに貼り付けられました

import threading 
import signal 
import sys 
import time 

shutdown = False 

def shutdownHook(sigNum, currentStackFrame): 
     global shutdown 
     print('shutdown') 
     shutdown = True 

def readInput(): 
     print('readInput') 
     print(sys.stdin.readline()) 
     print('done reading input') 

if __name__ == '__main__': 
     signal.signal(signal.SIGINT, shutdownHook) 
     signal.signal(signal.SIGTERM, shutdownHook) 

     inputThread = threading.Thread(name='input', target=readInput) 
     inputThread.start() 
     print('started input') 

     while not shutdown: 
       time.sleep(1) 
       print('waiting ' + str(shutdown)) 
     print('current thread' + str(threading.current_thread())) 
     print('end of program ' + str(shutdown)) 
     sys.exit(0) 
+0

「入力を読み終えましたか? –

+0

私はスレッド自体の問題だと思っていますが、もっと具体的に考えると –

+0

'ctl + c'は" shutdown "、" waiting true "、" current thread ... "、" end of program True " – pstanton

答えて

-1

スレッドをデーモンスレッドにすると、メインスレッドが終了するとシャットダウンされます。

inputThread = threading.Thread(name='input', target=readInput) 
inputThread.setDaemon(True) # add this line 
inputThread.start() 

また、指定した期間内にアクティビティが発生しないようにタイムラプスを追加することもできます。

time_limit_for_shutdown_in_secs = 10 
secs = 0 
while not shutdown: 
     if secs > time_limit_for_shutdown_in_secs: break 
     time.sleep(1) 
     print('waiting ' + str(shutdown)) 
     secs += 1 

print('current thread' + str(threading.current_thread())) 
print('end of program ' + str(shutdown)) 
sys.exit(0) 
+1

これは間違った答えです、あなたはOPに答えていない、あなたはただループを壊している!あなたがdownvotedされたくない場合は、あなたの答えを修正する –

+0

入力が一定の時間量のために受信されなかった場合には、プログラムを終了することです – johnII

+0

あなたは一度一度だけコードを実行していないので、最初の入力 –

1

あなたは(ここでは第二で定義する)一定時間後にあなたのプログラムにSIGALRMを送信するためにsignal.alarm()を使用することがあります。ここでは

if __name__ == '__main__': 
    # Set the signal handler and a 5-second alarm 
    signal.signal(signal.SIGALRM, shutdownHook) 
    signal.alarm(5) 

は、ドキュメントからcomplete working example次のとおりです。

ここには最小限のサンプルプログラムがあります。これはalarm()関数を使用して ファイルを開くのに費やす時間を制限します。これは、 ファイルがオンにならない可能性のあるシリアルデバイス用のファイルである場合に便利です。 は通常、os.open()が無期限にハングする原因となります。解決策は、ファイルを開く前に5秒のアラームを設定することです( )。操作に が長すぎる場合、アラーム信号が送信され、ハンドラは 例外を発生させます。 quoted the doc

Pythonのシグナルハンドラは、常にメインのPythonのスレッドで実行されているので、あなたのプログラムが終了していない理由については

import signal, os 

def handler(signum, frame): 
    print('Signal handler called with signal', signum) 
    raise OSError("Couldn't open device!") 

# Set the signal handler and a 5-second alarm 
signal.signal(signal.SIGALRM, handler) 
signal.alarm(5) 

# This open() may hang indefinitely 
fd = os.open('/dev/ttyS0', os.O_RDWR) 

signal.alarm(0)   # Disable the alarm 

があり、信号が別のスレッドで受信された場合でも 。つまり、 信号をスレッド間通信の手段として使用することはできません。 では、代わりにスレッド化モジュール の同期プリミティブを使用できます。また、メインスレッドのみが新しいシグナルハンドラを設定することができます。

つまり、プログラムを設計する方法でスレッドにシグナルが送信されないことを意味します。実際には、あなたが受け取るあなたのスレッドにシグナルを設定しようとValueError

プログラムが SIGTERMを受けた後に回し続ける理由です
ValueError: signal only works in main thread 

。スレッドがシグナルを受信しなかったためです。

代わりの解決方法はKill python thread using osを参照してください。

関連する問題