Python应用开发频繁假死的问题分析及解决

 更新时间:2024年08月02日 09:01:23   作者:设计笔记  
最近在开发一款自动化的应用,但是,在测试时,却发现了问题,当我点击暂停任务后,此时子线程被阻塞,如果我这个时候点击停止,那么就会任务结束,之后,如果我再点击开始运行,整个应用就会卡死,所以本文介绍了Python应用开发频繁假死的问题分析及解决,需要的朋友可以参考下

问题背景

最近在开发一款自动化的应用,其中有一个自动化任务会由下面这三个按钮控制:

逻辑也很简单,我大概画下图就是这样的:

但是,在测试时,却发现了问题:

当我点击暂停任务后,此时子线程被阻塞。如果我这个时候点击停止,那么就会任务结束。

之后,如果我再点击开始运行,整个应用就会卡死,非常离谱。

以下是简化后的代码:

 import threading
 import time
 from sample_singleton import singleton
 ​
 @singleton
 class TestThreadingEvent:
     def __init__(self):
         self._stop_event = threading.Event()
         self._pause_event = threading.Event()
         self._thread = None
 ​
     def set_stop(self):
         self._stop_event.set()
 ​
     def set_pause(self):
         self._pause_event.set()
 ​
     def start(self):
         print("任务开始")
         self._stop_event.clear()
         self._pause_event.set()
         print("开始执行")
         self._thread = threading.Thread(target=self._run)
         self._thread.start()
 ​
     def _run(self):
         count = 0
         while True:
             if self._stop_event.is_set():
                 print("任务被成功停止")
                 return
             print(f"是否需要暂停:{not self._pause_event.is_set()}")
             self._pause_event.wait()
             # 执行任务
             print(f"do something: {count}")
             time.sleep(1)
             count += 1
 ​
     def pause(self):
         print("点击了暂停")
         self._pause_event.clear()
         time.sleep(2)
 ​
     def stop(self):
         print("点击了停止")
         self._stop_event.set()
         print("成功停止")
         if self._thread is not None:
             self._thread.join()  # 确保线程终止
 ​
 ​
 print("我点击了开始")
 singletonA = TestThreadingEvent()
 singletonA.start()
 singletonA.pause()
 print("我点击了停止")
 singletonA.stop()
 print("我再次点击了开始")
 singletonA.start()

按照代码逻辑,我期待的结果是点击停止后,再次点击开始就可以开始重新运行,但是,虽然第一次显示停止了,可如果想再次开始,程序就会卡住不动了,下面为测试时输出的结果:

 我点击了开始
 任务开始
 开始执行
 是否需要暂停:False
 do something: 0
 我点击了暂停
 是否需要暂停:True
 我点击了停止
 成功停止
 # 然后在这里卡死

昨天下午一直在代码中断点找原因,搞了半天,都没能解决,下班前我甚至都在怀疑是不是 Python 代码的问题,想去看看源码找原因了。

找出原因

不过简化代码,确实比较有效,当我把整个流程简化成上面的代码,就比较方便找出问题出在哪里了。

是因为,当我点击“暂停”后,子线程进入阻塞状态。当执行“停止”操作时,使用了 self._thread.join(),这会导致主线程阻塞,直到子线程 self._thread 完成。然而,如果子线程因阻塞状态无法完成,就会导致主线程永久等待,结果是主线程卡死。

后面我看了下我们实际开发的应用代码,问题要更复杂点,但说到底,都是线程阻塞状态没有得到正确处理,导致的卡死。

解决办法

由于主线程卡死是子线程的阻塞状态造成的,可以通过以下两种方法解决:

  • 处理子线程阻塞:引入超时控制,确保子线程在合理时间内完成任务,并在必要时修改子线程的阻塞状态,以避免主线程长时间等待。
  • 销毁子线程:如果子线程在完成任务后不再需要重复使用,可以考虑在结束时直接销毁该线程,以避免阻塞主线程。

这两种方法可以有效避免主线程因子线程阻塞而卡死的问题。

以上就是Python应用开发频繁假死的问题分析及解决的详细内容,更多关于Python应用开发假死的资料请关注脚本之家其它相关文章!

相关文章

  • Python实现双进程防止单点故障实例深度探究

    Python实现双进程防止单点故障实例深度探究

    在分布式系统中,确保系统的高可用性是至关重要的,本文将深入探讨如何使用Python实现双进程自我保护机制,以应对单点故障,确保系统稳定运行,将通过详实的示例代码,介绍双进程自我保护的原理、实现步骤以及可能遇到的挑战
    2024-01-01
  • python圣诞树编写实例详解

    python圣诞树编写实例详解

    在本篇文章里小编给大家整理的是关于python圣诞树代码的相关内容,有兴趣的朋友们可以学习下。
    2020-02-02
  • python实现断点调试的方法

    python实现断点调试的方法

    本文主要介绍了python实现断点调试的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • Python利用PyVista进行mesh的色彩映射的实现

    Python利用PyVista进行mesh的色彩映射的实现

    这篇文章主要介绍了Python利用PyVista进行mesh的色彩映射的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • python读取Android permission文件

    python读取Android permission文件

    python解析json文件读取Android permission,同时可以学习到json的知识。
    2013-11-11
  • 移除Selenium中window.navigator.webdriver值

    移除Selenium中window.navigator.webdriver值

    这篇文章主要为大家介绍了如何正确的移除Selenium中window.navigator.webdriver的值方法步骤,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Pandas数据类型转换df.astype()及数据类型查看df.dtypes的使用

    Pandas数据类型转换df.astype()及数据类型查看df.dtypes的使用

    Python,numpy都有自己的一套数据格式,本文主要介绍了Pandas数据类型转换df.astype()及数据类型查看df.dtypes的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • Python文件操作和数据格式详解(简单简洁)

    Python文件操作和数据格式详解(简单简洁)

    文本处理是脚本语言的强项,下面这篇文章主要给大家介绍了关于Python文件操作和数据格式的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-05-05
  • 教你用一行Python代码实现GUI图形界面

    教你用一行Python代码实现GUI图形界面

    这篇文章主要介绍了教你用一行Python代码实现GUI图形界面,通过使用PySimpleGUI的popup_get_folder()方法,一行代码就能实现选择文件夹的操作,本文结合示例代码给大家介绍的非常详细,需要的朋友可以参考下
    2023-01-01
  • Python重命名文件并移动到对应文件夹

    Python重命名文件并移动到对应文件夹

    在日常的文件管理和处理过程中,我们可能会遇到需要将文件整理到不同文件夹中的需求,下面我们就来看看如何使用Python实现重命名文件并移动到对应文件夹吧
    2025-02-02

最新评论