简体   繁体   English

尝试在无限while循环内阻止导致线程退出

[英]try block inside infinite while loop causing thread to exit

I'm working on a Python program that uses a thread to infinitely read from a serial connection and handle exceptions based on input. 我正在研究一个Python程序,该程序使用线程从串行连接中无限读取并根据输入处理异常。

In essence: Within a thread, I want to do-something forever, raise an exception if something happens, return from exception and continue to do-something forever while handling any future exceptions. 本质上:在一个线程中,我想永远做某件事,如果发生某些事情引发异常,从异常中返回并继续做某件事,同时处理将来的任何异常。

I've created a test program to emulate this behavior using time.sleep() in order to isolate my problem. 我创建了一个测试程序来使用time.sleep()模拟此行为,以便隔离问题。

import threading
import time

class TimeError(Exception):
    def __init__(self, mesg):
        self.mesg=mesg

class myObject(object):

    def __init__(self):
        self.threadRunning=False

    def my_thread(self):
        threadCount=0

        try:
            while True:
                time.sleep(1)

                print "Child: {}".format(threadCount)
                threadCount = threadCount + 1
                if threadCount>=5:
                    raise TimeError("5 seconds elapsed!")

        except TimeError as e:
            print (e.mesg)

        print "Exiting thread!"
        self.threadRunning=False

    def my_parent(self): #start thread and wait
        childThread = threading.Thread(target=self.my_thread)
        childThread.daemon = True

        childThread.start()
        self.threadRunning = True

        parentCount=0
        while (self.threadRunning == True):
            print "Parent: {}".format(parentCount)
            parentCount = parentCount + 1
            time.sleep(1)

        print "Program complete."


fooObject = myObject()
fooObject.my_parent()

The output I received is 我收到的输出是

Parent: 0
Child: 0
Parent: 1
Child: 1
 Parent: 2
Child: 2
 Parent: 3
Child: 3
 Parent: 4
Child: 4
5 seconds elapsed!
Exiting thread!
 Parent: 5
Program complete.

I'm fairly new to Python and using exceptions (my background is C). 我对Python相当陌生,并且使用了异常(我的背景是C)。 I understand that exceptions are used to debug and recover from anomalies in normal execution flow. 我知道异常用于调试和从正常执行流程中的异常中恢复。 I've read that it's unwise to throw your own Exceptions , but for my final application, I must. 我读到抛出自己的Exceptions不明智的 ,但是对于我的最终应用程序,我必须这样做。

So, how do I get back to the While True infinite loop after handling an exception in the thread? 那么,在处理线程中的异常后如何返回While While无限循环? I want to keep incrementing threadCount and handling the exception, not exit the thread. 我想继续增加threadCount和处理异常,而不是退出线程。

By boiling down my code in order to ask this question I've found the solution. 通过精简我的代码以提出这个问题,我找到了解决方案。

In short, the while True loop should be surrounding the try/except block, not the other way around. 简而言之,while True循环应该围绕try / except块,而不是相反。 This is because... 这是因为...

If an exception occurs during execution of the try clause, the rest of the >clause is skipped. 如果在try子句执行期间发生异常,则>条款的其余部分将被跳过。 Then if its type matches the exception named after the >except keyword, the except clause is executed, and then execution continues >after the try statement. 然后,如果其类型与以> except关键字命名的异常匹配,则执行except子句,然后在try语句之后继续执行。

https://docs.python.org/2/tutorial/errors.html#handling-exceptions https://docs.python.org/2/tutorial/errors.html#handling-exceptions

My assumption was that an Exception behaved like an interrupt in that it went off to execute the handling code, then would return to the point in execution just after the Exception was raised. 我的假设是,异常的行为类似于中断,因为它开始执行处理代码,然后在引发异常后立即返回执行点。 This isn't C... 这不是C ...

Fixed code: 固定代码:

import threading
import time

class TimeError(Exception):
    def __init__(self, mesg):
        self.mesg=mesg

class myObject(object):

    def __init__(self):
        self.threadRunning=False

    def my_thread(self):
        threadCount=0


        while True:
            try:
                time.sleep(1)

                print "Child: {}".format(threadCount)
                threadCount = threadCount + 1
                if threadCount>=5:
                    raise TimeError("5 seconds elapsed!")

            except TimeError as e:
                print (e.mesg)

        print "Exiting thread!"
        self.threadRunning=False

    def my_parent(self): #start thread and wait
        childThread = threading.Thread(target=self.my_thread)
        childThread.daemon = True

        childThread.start()
        self.threadRunning = True

        parentCount=0
        while (self.threadRunning == True):
            print "Parent: {}".format(parentCount)
            parentCount = parentCount + 1
            time.sleep(1)

        print "Program complete."


fooObject = myObject()
fooObject.my_parent()

Intended output: 预期输出:

Parent: 0
Child: 0
Parent: 1
Child: 1
Parent: 2
Child: 2
Parent: 3
Child: 3
Parent: 4
Child: 4
 5 seconds elapsed!
Parent: 5
Parent: 6
 Child: 5
5 seconds elapsed!
Child: 6
 5 seconds elapsed!
Parent: 7
Parent: 8
 Child: 7
5 seconds elapsed!
Child: 8
 5 seconds elapsed!
...indefinately

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM