c++做网站网络公司做网站价格
2026/5/13 19:14:46 网站建设 项目流程
c++做网站,网络公司做网站价格,佛山做seo推广公司,找工作下载什么软件简要介绍#xff1a;QRunnable是轻量级的任务载体核心定位#xff1a;只封装「任务逻辑」#xff0c;不具备线程能力。QRunnable 的唯一核心作用是「打包要在子线程中执行的业务代码」#xff0c;它只回答「要做什么」#xff08;即 run() 方法中封装的逻辑#xff09;QRunnable是轻量级的任务载体核心定位只封装「任务逻辑」不具备线程能力。QRunnable的唯一核心作用是「打包要在子线程中执行的业务代码」它只回答「要做什么」即run()方法中封装的逻辑本身不是线程无法独立运行必须依赖QThreadPool才能被调度执行。「轻量级」的核心体现结构极简仅需重写一个run()方法即可使用无其他强制重写的抽象方法无额外开销不继承QObject没有 Qt 信号槽、事件循环等附加机制创建和销毁的资源消耗极低无需手动管理生命周期默认autoDeleteTrue任务执行完毕后QThreadPool会自动销毁其实例无需手动绑定finished信号和deleteLater()避免内存泄露且减少代码工作量。对比凸显轻量与QThread相比QThread既是「线程载体」又是「生命周期管理者」自带线程启停、事件循环等复杂逻辑而QRunnable只专注于「任务本身」把线程的创建、调度、复用全交给QThreadPool更适合执行简单、短期的临时任务。QThreadPool.globalInstance()是获取全局线程池实例的语句所属框架与核心类该语句依赖 Qt 框架的QThreadPool类该类是 Qt 提供的线程池管理工具用于统一管理、复用线程避免频繁创建 / 销毁线程带来的性能开销是 Qt 中实现多线程任务尤其是短小、大量的任务的常用方案。globalInstance()方法的核心作用globalInstance()是QThreadPool的静态方法static method它的核心功能不是创建新的线程池对象而是获取 Qt 框架内置的、整个应用程序级别的全局唯一线程池实例。这个实例是 Qt 在应用程序启动时自动初始化的全程单例唯一无需开发者手动创建QThreadPool对象直接通过该方法获取实例后即可随时复用全局线程池简化多线程代码实现。语句的执行结果与后续用途语句执行后随时可以引用指向这个全局唯一的 QThreadPool 实例而非创建新实例后续开发者可以通过实例调用QThreadPool的成员方法如start()提交任务、setMaxThreadCount()设置最大线程数等实现多线程任务的提交与管理。补充核心特性全局线程池的生命周期与整个 Qt 应用程序绑定应用程序退出时自动销毁无需开发者手动释放资源降低了多线程开发的资源管理成本。使用方法二者结合非常适合执行简单、短期的任务Qt 在应用程序启动初始化一个线程池实例QThreadPool.globalInstance()然后创建QRunnable实例再使用QThreadPool.globalInstance()实例的start()方法启动QRunnable实例与QThread 线程相比代码简洁且无需关心线程销毁线程池自动管理。最简化代码import sys import time from PySide6.QtCore import QMutex, QRunnable, QThreadPool, QMutexLocker from PySide6.QtWidgets import QApplication, QPushButton, QWidget, QVBoxLayout # 1. 包装QRunnable任务极简包装无需复杂继承逻辑 class Runnable(QRunnable): def __init__(self, buf_lock): super().__init__() self.buf_lock buf_lock # QRunnable接口的实现run()方法 def run(self): with QMutexLocker(self.buf_lock): # 临界区获取互斥锁后执行业务函数 print(临时线程获取锁执行操作) # 模拟耗时操作 time.sleep(5) # 耗时操作在互斥锁的临界区内执行 print(临时任务执行完毕) # 2. 按钮点击触发函数创建任务 提交到线程池无需手动启动线程 def on_button_clicked(lock): 点击按钮触发快速提交临时任务到线程池 runnable Runnable(lock) thread_pool.start(runnable) # 线程池自动分配线程执行任务 if __name__ __main__: app QApplication(sys.argv) lock QMutex() # 全局互斥锁 thread_pool QThreadPool.globalInstance() # 获取全局线程池无需手动创建 # 初始化按钮绑定点击事件 btn QPushButton(创建临时线程执行 1 操作) btn.clicked.connect(lambda: on_button_clicked(lock)) btn.show() sys.exit(app.exec())将任务封装成函数import sys import time from PySide6.QtCore import QMutex, QRunnable, QThreadPool, QMutexLocker from PySide6.QtWidgets import QApplication, QPushButton, QWidget, QVBoxLayout # 1. 定义简单的任务执行函数无需创建QObject/QThread子类仅处理核心逻辑 def task1(): print(临时线程1获取锁执行 1 操作) def task2(): print(临时线程2获取锁执行 2 操作) # 2. 包装QRunnable任务极简包装无需复杂继承逻辑 class Runnable(QRunnable): def __init__(self, buf_lock, task): super().__init__() self.buf_lock buf_lock self.task task # QRunnable接口的实现run()方法 def run(self): with QMutexLocker(self.buf_lock): # 临界区获取互斥锁后执行业务函数 self.task() # 模拟耗时操作 # time.sleep(5) # 耗时操作在互斥锁的临界区内执行 or time.sleep(5) # 耗时操作在互斥锁的临界区外执行可以体会一下二者的区别 print(f临时任务{self.task.__name__}执行完毕) # 3. 按钮点击触发函数创建任务 提交到线程池无需手动启动线程 def on_button_clicked(lock, task): 点击按钮触发快速提交临时任务到线程池 runnable Runnable(lock, task) thread_pool.start(runnable) # 线程池自动分配线程执行任务 if __name__ __main__: app QApplication(sys.argv) lock QMutex() # 全局互斥锁 thread_pool QThreadPool.globalInstance() # 获取全局线程池无需手动创建 # 初始化按钮绑定点击事件 btn1 QPushButton(创建临时线程执行 1 操作) btn1.clicked.connect(lambda: on_button_clicked(lock, task1)) btn2 QPushButton(创建临时线程执行 2 操作) btn2.clicked.connect(lambda: on_button_clicked(lock, task2)) form QWidget() layout QVBoxLayout(form) layout.addWidget(btn1) layout.addWidget(btn2) form.setLayout(layout) form.show() sys.exit(app.exec())将工作的对象封装为类import sys import time from PySide6.QtCore import QMutex, QRunnable, QThreadPool, QMutexLocker, QObject from PySide6.QtWidgets import QApplication, QPushButton, QWidget, QVBoxLayout # 工作的对象 class WorkObject(QObject): def __init__(self, lock): super().__init__() self.lock lock # 按钮点击触发函数创建任务 提交到线程池无需手动启动线程 def on_button_clicked(self): 点击按钮触发快速提交临时任务到线程池 runnable Runnable(self.lock) thread_pool.start(runnable) # 线程池自动分配线程执行任务 # 包装QRunnable任务 class Runnable(QRunnable): def __init__(self, buf_lock): super().__init__() self.buf_lock buf_lock # QRunnable接口的实现run()方法 def run(self): with QMutexLocker(self.buf_lock): # 临界区获取互斥锁后执行业务函数 print(f临时线程获取锁执行操作) # 模拟耗时操作 # time.sleep(5) # 耗时操作在互斥锁的临界区内执行 or time.sleep(5) # 耗时操作在互斥锁的临界区外执行 print(f临时任务执行完毕) if __name__ __main__: app QApplication(sys.argv) lock QMutex() # 全局互斥锁 thread_pool QThreadPool.globalInstance() # 获取全局线程池无需手动创建 obj_thread WorkObject(lock) # 创建对象线程对象 # 初始化按钮绑定点击事件 btn1 QPushButton(创建临时线程执行操作) btn1.clicked.connect(lambda: obj_thread.on_button_clicked()) btn1.show() sys.exit(app.exec())上面的代码每次点击按钮都定义了一个QRunnable并在线程池中自动运行运行完成后自动销毁。另外代码中模拟的耗时操作time.sleep(5)放在互斥锁的临界区内还是外执行区别还是很明显的。工程意义比如一个相机采图项目当从相机中获取到了像素数据后需要进行保存就可以把保存的操作封装为QRunnable并且只在互斥锁中执行内存拷贝写硬盘的操作不影响相机的采图线程import sys import time from copy import deepcopy from PySide6.QtCore import QMutex, QRunnable, QThreadPool, QMutexLocker, QThread, Signal from PySide6.QtWidgets import QApplication, QPushButton, QWidget, QVBoxLayout, QLabel def save_bmp(): global frame_data time.sleep(0.1) # 模拟复制像素数据到内存的耗时过程 print(f获取到了\{frame_data}\bmp数据到内存) def save_jpg(): global frame_data time.sleep(0.1) # 模拟复制像素数据到内存的耗时过程 print(f获取到了\{frame_data}\jpg数据到内存) # 包装QRunnable任务 class Runnable(QRunnable): def __init__(self, buf_lock, task): super().__init__() self.buf_lock buf_lock # 共享的互斥锁对象 self.task task # 任务函数 # QRunnable接口的实现run()方法 def run(self): with QMutexLocker(self.buf_lock): # 使用QMutexLocker自动获取/释放互斥锁 # 临界区获取互斥锁后执行业务函数 self.task() # 执行任务函数 print(f任务{self.task.__name__}已释放互斥锁开始在硬盘写数据) time.sleep(2) # 模拟保存文件的耗时过程 print(f任务{self.task.__name__}硬盘写数据完毕) # 3. 按钮点击触发函数创建任务 提交到线程池无需手动启动线程 def on_button_clicked(lock, task): 点击按钮触发快速提交临时任务到线程池 runnable Runnable(lock, task) # 创建QRunnable任务对象 thread_pool.start(runnable) # 线程池自动分配线程执行任务 # 4. 模拟相机的采样 class CameraQthread(QThread): outFrame Signal(int) # 模拟相机输出的帧数据 def __init__(self, lock): super().__init__() self.lock lock # 共享的互斥锁对象 self.frame_num 0 # 用帧数计数器模拟相机采样得到的帧数据 def run(self): global frame_data while True: with QMutexLocker(self.lock): time.sleep(0.2) # 模拟相机采样耗时 self.frame_num 1 # 帧数计数模拟采样到的数据 frame_data deepcopy(self.frame_num) # 模拟采样到的数据拷贝到全局的帧数据,深度拷贝防止数据被修改 self.outFrame.emit(self.frame_num) # 发送信号模拟界面显示相机采样到的图像 if __name__ __main__: app QApplication(sys.argv) lock QMutex() # 全局互斥锁 thread_pool QThreadPool.globalInstance() # 获取全局线程池无需手动创建 frame_data 0 # 全局帧数据模拟相机采样得到的数据 camera CameraQthread(lock) # 创建相机线程对象 camera.start() # 初始化按钮绑定点击事件 btn1 QPushButton(保存为bmp格式) btn1.clicked.connect(lambda: on_button_clicked(lock, save_bmp)) btn2 QPushButton(保存为jpg格式) btn2.clicked.connect(lambda: on_button_clicked(lock, save_jpg)) # 添加一个标签模拟相机的采样 label QLabel(相机帧数据) camera.outFrame.connect(lambda num:label.setText(f相机帧数据{num})) # 初始化窗口 form QWidget() layout QVBoxLayout(form) layout.addWidget(label) layout.addWidget(btn1) layout.addWidget(btn2) form.setLayout(layout) form.show() sys.exit(app.exec())从运行截图中可以看到由于将写硬盘这种耗时工作放在了互斥锁的临界区外互斥锁只在内存拷贝阶段对相机的采图有影响而保存到硬盘的操作对相机的采图没有任何影响。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询