質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
while

Whileは多くの言語で使われるコントロール構造であり、特定の条件が満たされる限り一連の命令を繰り返し実行します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

3362閲覧

whileループ内からCtrl+cで抜ける際のエラーに関して

253064

総合スコア0

while

Whileは多くの言語で使われるコントロール構造であり、特定の条件が満たされる限り一連の命令を繰り返し実行します。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

2クリップ

投稿2020/10/08 02:41

#プログラムの内容
1s毎にカウントアップとカウント数を表示すると同時にキーボードから入力があれば入力された内容を表示する
#問題点
Ctrl+Cでwhile分からbreakする際にエラーが発生するが、理由が理解できない。
エラーが発生しないように修正したい。
#環境
windows10 64bit
python
vscode
#エラー内容
Exception in thread Thread-2:
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\threading.py", line 932, in _bootstrap_inner
self.run()
in inputmsg
msg = input("")
EOFError
Exception ignored in: <module 'threading' from 'C:\ProgramData\Anaconda3\lib\threading.py'>
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\threading.py", line 1388, in _shutdown
lock.acquire()
KeyboardInterrupt:

import time import threading num = 0 #1sカウントの関数定義 def num1(): while True: try: global num print("num = " + str(num)) num += 1 time.sleep(1) except KeyboardInterrupt: Thread_1.join() print('num1 END') break #キーボード入力の関数定義 def inputmsg(): while True: try: #global msg #strはグローバル宣言なくても使える msg = input("") print(msg + ' 入力された内容') except KeyboardInterrupt: Thread_2.join() print('inputmsg END') break #同時起動の準備 Thread_1 = threading.Thread(target=num1) Thread_2 = threading.Thread(target=inputmsg) #プログラムの同時起動 Thread_1.start() Thread_2.start()

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

threadingにあまり詳しくないので嘘を書いていたら申し訳ないのですが、

KeyboardInterruptはメインスレッドにのみ送られていると思われます。
手元で実行してみたところ、num1のexceptもinputmsgのexceptも実行されなかったので
(詳しい人がいれば補足して頂きたい)

解決方法なのですが、メインスレッドでKeyboardInterrupt が捕捉できるので、その際に各スレッドに
対して終了するようにすればエラーは消えました。

変更点は

  • スレッド内の KeyboardInterrupt ハンドリングをやめた
  • StopRequestグローバル変数を追加(False=実行可 , True=停止要求)
  • 各スレッドで上記変数を見るように変更
  • inputmsg() はdaemon threadとしてメインスレッドとともに強制終了するように
import sys import time import threading num = 0 StopRequest = False #1sカウントの関数定義 def num1(): global StopRequest while (StopRequest == False): global num print("num = " + str(num)) num += 1 time.sleep(1) print("Thread num1 Stopped") #キーボード入力の関数定義 def inputmsg(): global StopRequest while (StopRequest == False): #global msg #strはグローバル宣言なくても使える try: msg = input("") print(msg + ' 入力された内容') except EOFError: # メインスレッドと共に停止される際に、WindowsではEOFErrorが発生するので # 発生したら停止と見なす。(しかし、スレッドは強制停止されるのでこの行は実行されない) print("Thread inputmsg Stopped") #同時起動の準備 Thread_1 = threading.Thread(target=num1) Thread_2 = threading.Thread(target=inputmsg) # inputmsgは input() で実行が停止し、ENTERが入力されるまで実行が止まるので # daemon threadとしてしまい、メインスレッド終了時に強制終了する Thread_2.daemon=True #プログラムの同時起動 Thread_1.start() Thread_2.start() while (Thread_1.is_alive()): try: Thread_1.join(1) except KeyboardInterrupt: print("!! Keyboard Interrupt") StopRequest = True Thread_1.join() # 終了待ち sys.exit()

投稿2020/10/08 05:21

編集2020/10/08 06:36
YakumoSaki

総合スコア2027

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

253064

2020/10/08 05:53

ご回答有難う御座います。 ctrl+Cによって終了することができました。 ただ、まだエラーは残るようで下記理由を考えたいと思います。 Exception in thread Thread-2: Traceback (most recent call last): File "C:\ProgramData\Anaconda3\lib\threading.py", line 932, in _bootstrap_inner self.run() File "C:\ProgramData\Anaconda3\lib\threading.py", line 870, in run self._target(*self._args, **self._kwargs) File "c:/Python-PG/00 test/20_while_threading2.py", line 27, in inputmsg msg = input("") EOFError
YakumoSaki

2020/10/08 06:37

WindowsだとEOFErrorが出るのが確認できたので、コードを修正しました。 手元のPython3.8.6 on Windows 10 で動作確認したので、これで如何でしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問