Я ищу способ вызвать исключение в цикле while True. Сигнал для возбуждения исключения возникает в потоке t_run, который постоянно проверяет глобальную логическую переменную, называемую pingresponse. Как только pingresponse станет равным «False», цикл while True должен быть немедленно прерван. Чего я не хочу, так это постоянно проверять переменную pingresponse в цикле while True, чтобы проверить, нужно ли вызывать исключение.
Мой черновик пока выглядит следующим образом:
import time
import threading
import random
def run():
# this thread continuously checks the pingresponse
global pingresponse
while True:
# simulating a random pingresponse
if random.random() > 0.8:
pingresponse = False
else:
pingresponse = True
time.sleep(0.001)
pingresponse = True
t_run = threading.Thread(target=run)
t_run.start()
while True:
i = 0
while True:
try:
print('While True loop iteration', i)
print('pingresponse:' ,pingresponse)
i += 1
# "do some work" which includes several consecutive and encapsulated while and for loops
time.sleep(1) # simulate "do some work" and prevent infinite looping if executed
# What I want is immediately interrupting the inner while True loop by raising an exception
# as soon as pingresponse was set to False in the t_run thread
# The exception should be raised independently of the current position in "do some work"
# What I don't want is to check the pingresponse variable all the time in "do some work":
# if not pingresponse:
# raise Exception
except Exception:
print('pingresponse was set to False in the t_run thread')
print('start while True loop again with iteration 0')
break
Связано: Остановить основной поток из дочернего потока , Как выйти из всего приложения из потока Python? ,
Если какой-либо из связанных вопросов и ответов отвечает на ваш вопрос, сообщите нам, чтобы мы могли пометить ваш как дубликат и не принимать мой ответ (я его удалю).
Я не знаю, почему вы изменили мой пример, чтобы «остановить все», но функция _thread.interrupt_main() для прерывания клавиатуры является возможным решением моей проблемы.
@user111029 user111029 Я сделал это, чтобы я остановился во время игры - я не хотел, чтобы там висели бесконечные циклы.
Используя метод от этого ответа до How to exit the entire application from a Python thread?
. Изменил ваш пример, чтобы остановить все при возникновении исключения. _thread.interrupt_main() вызовет прерывание клавиатуры в основном потоке.
import time
import threading
import _thread
import random
def run():
# this thread continously checks the pingresponse
global pingresponse
while True:
# simulating a random pingresponse
x = random.random()
print(f'x:{x:1.3f}')
if x > 0.98:
pingresponse = False
else:
pingresponse = True
time.sleep(0.001)
if not pingresponse:
_thread.interrupt_main()
break
pingresponse = True
t_run = threading.Thread(target=run)
t_run.start()
foo = True
while foo:
i = 0
while True:
try:
print('While True loop iteration', i)
print('pingresponse:' ,pingresponse)
i += 1
# "do some work" which includes several consecutive and encapsulated while and for loops
time.sleep(1) # simulate "do some work" and prevent infinite looping if executed
except KeyboardInterrupt as e:
print('pingresponse was set to False in the t_run thread')
print('start while True loop again with iteration 0')
# print(e)
foo = False
# raise
break
if foo: break
При использовании _thread.interrupt_main() могут быть некоторые вещи, которые вам нужно учитывать — вам следует потратить некоторое время на их изучение. Возможно, вы захотите включить в это путешествие сигнальный модуль .
Как мне захватить SIGINT в Python? выглядит достойно.
Отвечает ли это на ваш вопрос? Перехватывать исключение потока в вызывающем потоке в Python