掌握QT线程运行机制:创建与交叉执行方法

版权申诉
0 下载量 36 浏览量 更新于2024-12-05 收藏 1.07MB RAR 举报
资源摘要信息:"该资源文件名为'mythread_test.rar_qt thread_run',描述了一个使用Qt框架实现的线程程序。在这个程序中,用户可以创建并运行自己的线程,且线程的运行函数为run()。此外,该程序有两个线程交叉运行的特点,展示了多线程编程中的线程调度和同步的实现方法。" 一、Qt框架基础知识 Qt是一个跨平台的C++库,用于开发图形用户界面应用程序,以及非GUI程序,如命令行工具和服务器。它提供了丰富的窗口部件集,用于实现GUI程序的各种功能,并且支持多线程开发。Qt通过QThread类抽象了线程的概念,提供了方便的API来创建、运行和管理线程。 二、QThread类基础 1. QThread类是Qt提供的用于处理线程的抽象基类,它允许开发者创建自己的线程类。 2. QThread提供了start()方法来启动线程,该方法会调用run()函数。因此,在继承QThread的子类中,需要实现run()方法。 3. QThread还提供了quit()和terminate()方法来优雅地停止线程运行。 4. 在处理线程间通信和数据共享时,Qt提供了信号与槽机制、互斥锁(QMutex)、读写锁(QReadWriteLock)、条件变量(QWaitCondition)等同步机制。 三、线程运行函数run()的实现 在使用QThread时,开发者需要创建一个继承自QThread的子类,并重写run()方法。run()方法是线程的入口函数,当线程启动时,QThread会自动调用这个方法。 ```cpp class MyThread : public QThread { void run() override { // 线程体代码 } }; ``` 在上述例子中,MyThread类继承自QThread,并重写了run()函数,用于定义线程执行的具体任务。 四、实现两个线程交叉运行的方法 要实现两个线程交叉运行,需要考虑线程的调度和同步。以下是几种可能的方法: 1. 信号与槽机制 可以使用Qt的信号与槽机制来进行线程间的通信。当一个线程执行到某个特定点时,它可以发出一个信号,对应的槽函数中可以包含另一个线程应该执行的操作。 2. 互斥锁 互斥锁可以用来保护共享资源,确保同一时间只有一个线程可以访问。利用互斥锁可以控制线程的交叉执行,防止竞态条件的发生。 3. 条件变量 条件变量可以用来等待或广播某个条件的发生。当一个线程到达某个点,它可能需要等待一个条件变为真,这时可以使用条件变量。另一个线程在条件发生改变时可以发出广播信号,从而使得等待的线程继续执行。 4. 使用QtConcurrent模块 QtConcurrent模块提供了高级接口用于并发编程。它允许开发者不直接操作线程而执行并行任务。使用这个模块,可以简化交叉运行线程的复杂性。 五、Qt多线程编程的注意事项 在进行Qt多线程编程时,需要特别注意以下几个问题: 1. 线程安全:在多线程环境下,对共享资源的访问需要进行同步,避免数据竞争和条件竞争。 2. GUI线程与工作线程:在GUI应用程序中,所有与界面相关的操作必须在主线程(GUI线程)中执行。工作线程不能直接操作GUI组件,必须通过信号与槽机制与主线程通信。 3. 避免阻塞主线程:长时间运行的任务不应该放在主线程中执行,以免阻塞GUI响应。 总结:通过本资源文件,用户可以学习到如何使用Qt框架创建和管理线程,实现线程的基本操作如启动、运行和停止,并理解如何通过不同机制实现多线程的交叉运行。同时,用户还需注意在多线程编程中保证线程安全和效率,确保程序的稳定性和响应性。

使用QTimer对象代替QBasicTimer对象,修改程序class MyWindow(QWidget): def init(self): super().init() self.thread_list = [] self.color_photo_dir = os.path.join(os.getcwd(), "color_photos") self.depth_photo_dir = os.path.join(os.getcwd(), "depth_photos") self.image_thread = None self.saved_color_photos = 0 # 定义 saved_color_photos 属性 self.saved_depth_photos = 0 # 定义 saved_depth_photos 属性 self.init_ui() def init_ui(self): self.ui = uic.loadUi("C:/Users/wyt/Desktop/D405界面/intelrealsense1.ui") self.open_btn = self.ui.pushButton self.color_image_chose_btn = self.ui.pushButton_3 self.depth_image_chose_btn = self.ui.pushButton_4 self.open_btn.clicked.connect(self.open) self.color_image_chose_btn.clicked.connect(lambda: self.chose_dir(self.ui.lineEdit, "color")) self.depth_image_chose_btn.clicked.connect(lambda: self.chose_dir(self.ui.lineEdit_2, "depth")) def open(self): self.profile = self.pipeline.start(self.config) self.is_camera_opened = True self.label.setText('相机已打开') self.label.setStyleSheet('color:green') self.open_btn.setEnabled(False) self.close_btn.setEnabled(True) self.image_thread = ImageThread(self.pipeline, self.color_label, self.depth_label, self.interval, self.color_photo_dir, self.depth_photo_dir, self._dgl) self.image_thread.saved_color_photos_signal.connect(self.update_saved_color_photos_label) self.image_thread.saved_depth_photos_signal.connect(self.update_saved_depth_photos_label) self.image_thread.start() def chose_dir(self, line_edit, button_type): my_thread = MyThread(line_edit, button_type) my_thread.finished_signal.connect(self.update_line_edit) self.thread_list.append(my_thread) my_thread.start()

2023-05-26 上传