Как вызвать исключение в цикле из потока в python?

Я ищу способ вызвать исключение в цикле 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

Akihito KIRISAKI 26.12.2020 15:42

Если какой-либо из связанных вопросов и ответов отвечает на ваш вопрос, сообщите нам, чтобы мы могли пометить ваш как дубликат и не принимать мой ответ (я его удалю).

wwii 26.12.2020 17:02

Я не знаю, почему вы изменили мой пример, чтобы «остановить все», но функция _thread.interrupt_main() для прерывания клавиатуры является возможным решением моей проблемы.

user111029 26.12.2020 18:13

@user111029 user111029 Я сделал это, чтобы я остановился во время игры - я не хотел, чтобы там висели бесконечные циклы.

wwii 26.12.2020 18:26
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
5
413
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Используя метод от этого ответа до 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? выглядит достойно.

Другие вопросы по теме