首页 > 系统相关 >进程已结束,退出代码为 -1073740791 (0xC0000409)。QThread: Destroyed while thread is still running

进程已结束,退出代码为 -1073740791 (0xC0000409)。QThread: Destroyed while thread is still running

时间:2024-09-23 14:21:52浏览次数:3  
标签:index thread self 1073740791 running 线程 def channel

        在使用pycharm写代码发现代码运行不了,进程已结束,退出代码为 -1073740791 (0xC0000409),但是又不提示具体错在哪。为了得到更加清晰的错误原因,可如下操作:

        ①点击debug旁边的三个小点more actions,点击编辑。

        ②勾选 在控制台中模拟终端。

        此时我们能看到更多的报错信息,出现了原因QThread: Destroyed while thread is still running。这表明这个代码中试图销毁正在运行的线程。

        随后对代码进行分析。

class TestThread(QThread):
    def __init__(self, channel_index):
        super().__init__()
        self.channel_index = channel_index

    def run(self):
        # 线程的测试逻辑
        logging.info(f"开始测试通道 {self.channel_index + 1}")
        try:
            # 在这里放置实际的测试代码,
            result = utils.copy_check_audio()
            logging.info(f"通道 {self.channel_index + 1} 测试完成")
        except Exception as e:
            logging.error(f"通道 {self.channel_index + 1} 测试失败: {e}")

class Window_Main(QMainWindow):
    def main_test(self):
        thread = TestThread(current_channel)
        thread.start()

        发现是我在main_tes函数中实例化的一个线程,而这个线程对象是一个局部变量,当main_test执行运行完成后,thread的引用计数器减一,此外代码中没有在别的地方引用该对象,因此此时引用计数器为0,触发python的垃圾回收机制,thread对象被回收,但是此时这个线程还在运行run中的代码,这才导致出现进程已结束,退出代码为 -1073740791 (0xC0000409)的错误。   

解决方法

        保留对线程的引用防止销毁:将线程对象存储在self.threads中,此时就是main_test执行完毕,这个对象仍然在被引用,python的垃圾回收机制就不会自动销毁他,这样当 thread.run() 完成后,线程会自己进入 finished 状态。

class TestThread(QThread):
    def __init__(self, channel_index):
        super().__init__()
        self.channel_index = channel_index

    def run(self):
        # 线程的测试逻辑
        logging.info(f"开始测试通道 {self.channel_index + 1}")
        try:
            # 在这里放置实际的测试代码,
            result = utils.copy_check_audio()
            logging.info(f"通道 {self.channel_index + 1} 测试完成")
        except Exception as e:
            logging.error(f"通道 {self.channel_index + 1} 测试失败: {e}")

class Window_Main(QMainWindow):
    self.threads = []
    def main_test(self):
        thread = TestThread(current_channel)
        self.threads.append(thread) #保留对线程的引用防止销毁
        thread.start()
        

但是可以看到,这样也还有一个问题,当 thread.run() 完成后,线程会进入 finished 状态,但thread的引用计数器不为0,对象本身不会被自动销毁当开的线程数越来越对,self.threads越来越大,占用系统资源,拖慢运行速度。因此需要手动移除对该线程的引用。最终改进后的代码如下:

class TestThread(QThread):
    def __init__(self, channel_index):
        super().__init__()
        self.channel_index = channel_index

    def run(self):
        # 线程的测试逻辑
        logging.info(f"开始测试通道 {self.channel_index + 1}")
        try:
            # 在这里放置实际的测试代码,
            result = utils.copy_check_audio()
            logging.info(f"通道 {self.channel_index + 1} 测试完成")
        except Exception as e:
            logging.error(f"通道 {self.channel_index + 1} 测试失败: {e}")

class Window_Main(QMainWindow):
    self.threads = []
    def main_test(self):
        thread = TestThread(current_channel)
        thread.finished.connect(self.on_thread_finished)  # 当线程结束时调用
        self.threads.append(thread) #保留对线程的引用防止销毁
        thread.start()

    def on_thread_finished(self):
        # 清理已完成的线程
        self.threads = [t for t in self.threads if t.isRunning()]

标签:index,thread,self,1073740791,running,线程,def,channel
From: https://blog.csdn.net/qq_46161199/article/details/142456137

相关文章

  • ubuntu网口状态:DOWN、UP、RUNNING
    对Ubuntu系统中网口不同状态的理解一、ipaipa可查看所有网口状态二、ifconfigifconfig可查看被up起来的网口信息三、DOWN、UP、RUNNING当网口状态为DOWN时可用ifconfigens33up将网口up网口状态必须为UP才能设置IP、子网掩码等这个接口被标记为UP(已启用)、BR......
  • 【Java】了解线程 Thread 类的使用,
    线程是什么线程是操作系统中调度的基本单位,是比进程更小的执行单元。线程在进程内部运行,共享该进程的资源,如内存和文件句柄,但每个线程都有自己的执行栈和程序计数器。线程的主要特点包括:轻量级:线程相较于进程更加轻量,创建和销毁的开销较小。共享资源:同一进程中的线程共享该进程的内......
  • 【Java】深入解析ThreadLocal——Java并发编程的秘密武器
            ThreadLocal被称为线程局部变量,用于在线程中保存数据。由于在ThreadLocal中保存的数据仅属于当前线程,所以该变量对其他线程而言是隔离的,也就是说该变量是当前线程独有的变量。        ThreadLocal用于在同一个线程间,在不同的类和方法之间共享数据......
  • ScheduledThreadPoolExecutor
    总结继承自ThreadPoolExecutor并实现了ScheduledExecutorService接口。提供了基于线程池的定时任务调度功能,允许你安排任务在未来某个时间点执行一次,或者周期性地重复执行。特性定时任务:可以安排任务在指定延迟后执行。周期性任务:可以安排任务按照固定的时......
  • ThreadPoolExecutor 与 ForkJoinPool比较
    都是Java并发包java.util.concurrent中用于执行任务的线程池,但它们的设计目的和适用场景有所不同。下面是两者之间的主要区别:设计目标ThreadPoolExecutor:主要用于处理大量异步任务。适用于各种类型的任务,特别是那些独立运行且不需要相互协作的任务。提供了高度的......
  • C# 报错:System.Threading.ThreadStateException:”当前线程不在单线程单元中,因此无法
    原因分析System.Threading.ThreadStateException 错误通常发生在尝试在非UI线程中创建或访问 ActiveX 控件(如COM 组件)时。在 Windows Forms应用程序中,所有 UI操作必须在创建该UI 的线程(通常是主线程)上执行。解决方案要解决这个问题,你需要确保在 UI 线程上创建......
  • C++标准的一些特性记录:C++11的thread_local
    文章目录thread_localthread_local在多线程的编程环境里,一般来说,所有的线程都是共享同一个内存空间,也就是说如果定义一个变量,这个变量是被所有线程共享的,所以多个变量在访问同一个变量时,是需要加锁机制的,否则就会出现问题。在C++11中,引入了一个关键字thread_local......
  • 【Java基础】ThreadLocal<LoginUser>:存储登录用户信息
    ......
  • [ERROR] Error log throttle: 'Can't create thread to handle new connection' erro
    日常巡查中发现mysql日志中有大量报错:2024-09-1202:51:0219177[ERROR]Errorlogthrottle:3'Can'tcreatethreadtohandlenewconnection'error(s)suppressed2024-09-1202:51:0219177[ERROR]Can'tcreatethreadtohandlerequest(errno=......
  • android HandlerThread post后 7s才执行
    在Android中,HandlerThread是用来创建一个具有Looper的线程,这样可以在该线程上处理消息和运行任务。当你在HandlerThread上使用Handler的post()方法发送一个Runnable任务时,这个任务会被添加到MessageQueue中,并且会在Looper的主循环中被处理。如果你发现任务在post()之后大约7秒才被......