为了账号安全,请及时绑定邮箱和手机立即绑定

停止子线程中的主线程

停止子线程中的主线程

翻翻过去那场雪 2021-03-22 18:19:36
我正在编写一个python程序,在主要功能中,我正在启动一个连续运行的线程。启动线程后,主函数进入while循环,在此循环中持续接收用户输入。如果子线程中有异常,我也想结束main函数。最好的方法是什么?
查看完整描述

2 回答

?
冉冉说

TA贡献1877条经验 获得超1个赞

具有“控制”其父线程的线程不是一个好习惯。对于主线程来说,管理/监视/控制它启动的线程更有意义。


因此,我的建议是,您的主线程启动2个线程:您已经拥有的一个线程,该线程在某个时候结束/引发异常,以及一个读取用户输入的线程。现在,主线程等待(joins)前者完成,并在完成后退出。


from threading import Thread

import time


class ThreadA(Thread):

    def run(self):

        print 'T1: sleeping...'

        time.sleep(4)

        print 'T1: raising...'

        raise RuntimeError('bye')


class ThreadB(Thread):

    def __init__(self):

        Thread.__init__(self)

        self.daemon = True

    def run(self):

        while True:

            x = raw_input('T2: enter some input: ')

            print 'GOT:', x


t1 = ThreadA()

t2 = ThreadB()

t1.start()

t2.start()

t1.join()  # wait for t1 to finish/raise

print 'done'

由于ThreadB是守护程序,因此我们不必显式使其停止或加入。当主线程退出时,它也会退出。


IMO,无需诉诸信号之类的低级内容。该解决方案甚至不需要使用try-except(尽管您可能会决定要使用try-exceptinThreadA来使其干净退出)。


查看完整回答
反对 回复 2021-03-23
?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

Python使您可以通过信号模块访问此系统调用,因此您可以为其注册信号处理程序SIGINT并执行您喜欢的任何事情。SIGINT顺便说一句,默认处理程序仅引发KeyboardInterrupt异常,因此,如果您不想使用信号,则可以将整个程序放在try / except结构中,或多或少获得相同的效果。由于您希望在子线程发生任何崩溃时停止主线程,因此只需将整个while循环放入except Exception:try-except块中即可。

这应该可以工作,但是需要一些背景信息-Python的信号模块文档明确指出,当多个线程正在运行时,只有主线程(即,在进程启动时创建的线程)将接收信号(对您而言,这无关紧要,因为您想要主线程中的信号)。因此,信号处理程序将仅在一个线程中执行,而不是在所有线程中执行。为了使所有线程都停止响应信号,您需要主线程的信号处理程序将停止消息传递给其他子线程。这可以通过不同的方式完成,最简单的方法是让主线程翻转布尔变量的值,即所有子线程也都拥有引用。


查看完整回答
反对 回复 2021-03-23
  • 2 回答
  • 0 关注
  • 266 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号