Qt线程:QThread

2023-05-16

一、描述

一个QThread对象管理程序内的一个线程,QThreads在run()中开始执行。默认情况下,run()通过调用exec()启动事件循环,并在线程内部运行一个Qt事件循环。

可以通过使用 QObject::moveToThread() 将对象移动到线程来使用它们。

 class Worker : public QObject
 {
     Q_OBJECT

 public slots:
     void doWork(const QString &parameter)
     {
         QString result;
         /* ... 这里是昂贵的或阻塞的操作 ... * /
         emit resultReady(result);
     }
 signals:
     void resultReady(const QString &result);
 };

 class Controller : public QObject
 {
     Q_OBJECT
     QThread workerThread;
 public:
     Controller() 
     {
         Worker *worker = new Worker;
         worker->moveToThread(&workerThread);
         connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
         connect(this, &Controller::operate, worker, &Worker::doWork);
         connect(worker, &Worker::resultReady, this, &Controller::handleResults);
         workerThread.start();
     }
     ~Controller()
     {
         workerThread.quit();
         workerThread.wait();
     }
 public slots:
     void handleResults(const QString &);
 signals:
     void operate(const QString &);
 };

Worker 槽内的代码将在单独的线程中执行。可以自由地将 Worker 槽连接到来自任何对象、任何线程中的任何信号。跨不同线程连接信号和槽是安全的。

另一种使代码在单独线程中运行的方法是将 QThread 子类化并重新实现 run()。例如:

 class WorkerThread : public QThread
 {
     Q_OBJECT
     void run() override 
     {
         QString result;
         /* ... 这里是昂贵的或阻塞的操作 ... * /
         emit resultReady(result);
     }
 signals:
     void resultReady(const QString &s);
 };

 void MyObject::startWorkInAThread()
 {
     WorkerThread *workerThread = new WorkerThread(this);
     connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults);
     connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
     workerThread->start();
 }

示例中,线程将在 run 函数返回后退出。除非调用 exec(),否则线程中不会运行任何事件循环。

QThread 实例除了run()函数在新线程中执行,其他所有函数都在QThread 实例所在的线程中执行。这样可能会则从两个不同的线程访问同一个成员变量变量,要注意检查这样做是否安全。


二、类型成员

1、enum QThread::Priority:此枚举类型指示操作系统应如何调度新创建的线程。

  • IdlePriority:仅当没有其他线程正在运行时才调度。
  • LowestPriority:调度频率低于 LowPriority。
  • LowPriority:调度频率低于 NormalPriority。
  • NormalPriority:操作系统的默认优先级。
  • HighPriority:比 NormalPriority 更频繁地调度。
  • HighestPriority:比 HighPriority 更频繁地调度。
  • TimeCriticalPriority:尽可能经常安排调度。
  • InheritPriority:使用与创建线程相同的优先级。这是默认设置。

三、成员函数

1、[signal] void finished()

该信号在线程完成执行之前发出。当这个信号发出时,事件循环已经停止运行。除了延迟删除事件外,线程中将不再处理更多事件。该信号可以连接到 QObject::deleteLater(),以释放该线程中的对象。

注意:这是私有信号。 它可以用于信号连接,但不能由用户发射。

 2、void quit()

告诉线程的事件循环以返回码 0(成功)退出。 相当于调用 exit(0)。如果线程没有事件循环,则此函数不执行任何操作。此函数是线程安全的。

3、void start(QThread::Priority priority = InheritPriority)

通过调用 run() 开始执行线程。 操作系统会根据参数中设置的优先级调度线程。如果线程已经在运行,这个函数什么都不做。

优先级参数的效果取决于操作系统的调度策略。在不支持线程优先级的系统上,优先级将被忽略(如 Linux系统 )。

4、[signalvoid started()

当相关线程开始执行时,在调用 run() 函数之前,该信号从相关线程发出。这是私有信号,可以用于信号连接,但不能由用户发射。

5、void terminate()

终止线程的执行。线程可能会也可能不会立即终止,这取决于操作系统的调度策略。确保在terminate()之后调用 wait()。

当线程终止时,所有等待线程完成的线程都会被唤醒。

警告:此功能很危险,不鼓励使用。线程可能在其代码路径中的任何一点终止。修改数据时可能终止线程,线程将没有机会自行清理,解锁任何持有的互斥锁等。简而言之,只有在绝对必要时才使用此功能。

可以通过调用 setTerminationEnabled() 显式启用或禁用终止。在禁用终止时调用此函数会导致终止被推迟,直到重新启用终止。

6、~QThread()

销毁线程。删除 QThread 对象不会停止它管理的线程的执行。删除正在运行的 QThread将导致程序崩溃。应在删除 QThread 之前等待finished()信号。

7、[static] QThread *create(Function &&f, Args &&... args)

      [static] QThread *create(Function &&f)

创建一个新的 QThread 对象,该对象将使用参数 args 执行函数 f。

新线程没有启动,它必须通过显式调用 start() 启动。

注意:此函数仅在使用 C++17 时可用。

警告:不要在返回的 QThread 实例上多次调用 start(), 这样做会导致未定义的行为。

例:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    int i = 0;
    QThread * t = QThread::create([i]()mutable
    {
        while(i < 3)
        {
            qDebug()<<i;
            ++i;
        }
        qDebug()<<"lambda创建的子线程ID:"<<QThread::currentThreadId();
    });
    QObject::connect(t,&QThread::finished,[t]
    {
        qDebug()<<"线程是否仍在运行:"<<t->isRunning();
        t->deleteLater();
    });
    qDebug()<<"主线程ID:"<<QThread::currentThreadId();
    t->start();
}

 8、[static] QThread *currentThread()

返回指向当前执行线程的指针。

9、[static] Qt::HANDLE currentThreadId() 

返回当前正在执行的线程的线程句柄。警告:此函数返回的句柄用于内部目的,不应在任何应用程序代码中使用。

10、int exec()

进入事件循环并等待 exit() 被调用,返回传递给 exit() 的值。如果 exit() 是通过 quit() 调用的,则返回的值为 0。此函数从 run() 内部调用。需要调用这个函数来启动事件处理。

11、void exit(int returnCode = 0)

线程的事件循环以返回码returnCode 退出。

调用此函数后,线程离开事件循环并从对 QEventLoop::exec() 的调用返回。QEventLoop::exec() 函数返回 returnCode。

按照惯例,returnCode 为 0 表示成功,任何非零值表示错误。

12、[static] int idealThreadCount()

返回可以在系统上运行的理想线程数。这是通过查询系统中的实际和逻辑处理器内核数量来完成的。 如果无法检测到处理器内核数,则此函数返回 1。

13、bool isInterruptionRequested()

如果应停止在此线程上运行的任务,则返回 true。 requestInterruption() 可以请求中断。

此函数可用于使长时间运行的任务完全可中断。注意不要太频繁地调用它,以保持低开销。只能在线程本身内调用。

在长时间执行的任务中加上这个判断。如果有很消耗资源的情况可以中断线程。

14、void requestInterruption()

请求中断线程。该请求是建议性的,由线程上运行的代码决定是否以及如何应对此类请求。此函数不会停止在线程上运行的事件循环。

15、int loopLevel()

返回线程的当前事件循环级别。只能在线程本身内调用,即当它是当前线程时。

16、[static] void msleep(unsigned long msecs) (毫秒)

        [static] void sleep(unsigned long secs) (秒)

        [static] void usleep(unsigned long usecs) (微秒)

强制当前线程休眠。如果需要等待某个条件的达成,则应避免使用此函数改用信号槽。此功能不保证准确性。

17、void run()

线程的起点。调用 start() 后,新创建的线程调用此函数。默认实现只是调用 exec()。可以重新实现此功能以自定义线程操作。从此方法返回将结束线程的执行。

18、void setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)

设置线程的事件调度程序。在使用 start() 启动线程之前,或者在主线程的情况下,在实例化 QCoreApplication 之前调用才有效。

19、void setStackSize(uint stackSize)

将线程的最大堆栈大小设置为 stackSize。 如果 stackSize 大于零,则最大堆栈大小设置为 stackSize 字节,否则最大堆栈大小由操作系统自动确定。

警告:大多数操作系统对线程堆栈大小设置了最小和最大限制。 如果堆栈大小超出这些限制,线程将无法启动。

20、[static protected] void setTerminationEnabled(bool enabled = true)

启用或禁用当前线程的终止该线程必须已由 QThread 启动。

当 enabled 为 false 时,终止被禁用。以后对 terminate() 的调用将不会生效。直到设置setTerminationEnabled(true)时才会生效
当 enabled 为 true 时,终止被启用。以后对 terminate() 的调用将正常终止线程。

21、bool wait(QDeadlineTimer deadline = QDeadlineTimer(QDeadlineTimer::Forever))

        bool wait(unsigned long time)

阻塞当前调用QThread对象的线程,直到满足以下任一条件:

  • QThread对象关联的线程已完成执行(即当它从 run() 返回时)。如果线程已完成执行,此函数将返回 true。如果线程尚未启动,它也会返回 true。
  • 截止时间已到。如果达到最后期限,此函数将返回 false(线程还在继续执行)。

设置为 QDeadlineTimer::Forever(默认值)的截止时间计时器永远不会超时,在这种情况下,该函数仅在线程从 run() 返回或线程尚未启动时返回。

class myThread : public QThread
{
public:
    myThread(){}
protected:
    void run()override
    {
        int n = 0;
        for(int i = 0;i < 2000000000;++i)
        {
            if(i % 266 == 0)
                ++n;
        }
        qDebug()<<"n = "<<n;
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc,argv);
    myThread thread;
    thread.start();
    qDebug()<<thread.wait(1000);
    qDebug()<<"runing";
    Widget w;
    w.show();
    a.exec();
}

 22、[static] void yieldCurrentThread()

将当前线程的执行交给另一个可运行线程(如果有)。操作系统决定切换到哪个线程。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt线程:QThread 的相关文章

  • pyqt5 Qthread事件 进度条 案例

    pyqt5 Qthread事件 进度条 案例 代码 xff1a from PyQt5 import QtWidgets span class token punctuation span QtCore import sys from PyQ
  • Qt线程池waitForDone+等待框

    QThreadPool waitForDone 可阻塞线程 采用std function方式将其置于其它线程执行 避免阻塞线程同时可设置等待框 其它线程 生存期 单纯不阻塞线程可以直接不使用waitForDone 一 调用 DlgProce
  • QT多线程(QThread)小结

    QThread只有run函数是在新线程里的 其他所有函数都在QThread生成的线程里 如果QThread是在ui所在的线程里生成 那么QThread的其他非run函数都是和ui线程一样的 所以 QThread的继承类的其他函数尽量别要有太
  • 启动时将参数传递给 pyqt 线程

    当线程启动 start 时 有什么方法可以将参数传递给 QThread 吗 我在 stackoverflow 中找到了一个使用 pyqt 线程的示例 但我想知道如何传递参数 以防我希望工作线程处理我传递给其 run 函数的数据 我参考的帖子
  • 让主线程等待,直到所有其他 Qthread 完成

    有没有办法强制主线程等待 直到从它创建的所有线程完成其工作 然后再完成程序 我是说 int main QthreadClass a in cons a thread is created and running QthreadClass b
  • Qt中线程间通信的实现

    我在实现以下场景时遇到问题 我的问题陈述是这样的 我有 3 个线程 ThreadCamera 用于从相机中抓取帧 用于处理帧的 ThreadProcess 使用 OpenCV 对捕获的图像 帧进行一些图像处理 和用于显示图像的主 GUI 线
  • GUI 在循环时变得无响应

    单击按钮后 表单将变得无响应 直到解析函数完成其工作 我想将 searchAll 函数移至线程 我确实阅读了类似问题的几个答案 但我不明白如何 class MyForm QDialog def init self super init se
  • PySide 将信号从 QThread 传递到另一个 QThread 中的槽

    我通过移动解决了我的问题mySubQThread run 进入myQThread run 也就是说 我仍然想知道为什么我之前尝试的方法不起作用 我对线程很陌生 我遇到了这个问题 我认为我可能处理问题的方式是错误的 无论如何 我对不同的方法持
  • PySide2 Qthread 崩溃

    由于 Qtcore Signal 我想使用 PySide2 Qtcore Qthread 但最终出现此错误 进程已完成 退出代码为 1073740791 from PySide2 QtCore import QThread class Th
  • QObject 无法为位于不同线程中的父级创建子级

    您好 需要从后台进行一些套接字通信 我使用过QtConcurrent run对此 但给我警告 QObject Cannot create children for a parent that is in a different thread
  • 从非 UI QThread 修改 QStandardItemModel?

    我有绑定的 Qt4 应用程序QStandardItemModel to the QListView并从后台 非 UI 线程更新模型 有时 当QStandardItem s setText 方法从非 UI 线程中反复调用 应用程序将在 dat
  • QSocketNotifier:无法从另一个线程启用或禁用套接字通知程序

    我尝试使用 QT 构建一个多线程游戏服务器 因此 每个客户端都是一个基于 QThread 的独立线程 现在我需要将数据发送到同一游戏室中的其他客户端 在其他线程中 例如 当房主关闭游戏房间时 游戏服务器需要向同一 soom 中的其他客户端发
  • PyQt 从 GUI 获取值

    我使用构建了一个用户界面QtDesigner然后转换 ui to py 用户界面有不同comboBox and textBox单击 运行 按钮后我想从中读取值 运行函数 然后在计算完成后填充用户界面的其他文本框 但是当我改变的值comboB
  • QThread finish() 信号永远不会发出

    所以我有一个有2个槽的工作类 StartWork 和StopWork StartWork 一个运行无限循环 它只是不停地读取和读取相机输入 而StopWork 方法只设置一个bool变量设置为 false 因此 StartWork 内的循环
  • 如何将 lambda 函数排队到 Qt 的事件循环中?

    基本上我需要在 Java 中完成同样的事情 SwingUtilities invokeLater gt function 或者像 JavaScript 中这样 setTimeout gt function 0 但有了 Qt 和 lambda
  • 为什么我的 QThread 持续使 Maya 崩溃?

    我有一个 UI 我想在 Maya 内部使用线程 这样做的原因是这样我可以运行 Maya cmds 而无需挂起 冻结 UI 同时使用进度条等更新 UI 我已经阅读了 StackOverflow 中的一些示例 但我的代码每次运行时都会崩溃 我遵
  • 如何停止线程 - Qthread

    我必须在按下两个不同的按钮时启动 停止线程 请指出我的代码是否正确 我是否错过了 connect 调用中的某些内容 Problem我面临的是 在我的线程上调用 quit 后 然后我等待我的线程完成 但在线程上调用 wait never re
  • 从线程接收数据后pyqt主窗口不断崩溃

    我有一个 QMainWindow 启动 QThread 并等待来自网络的数据 当收到任何数据时更新 UI 问题是 它有时会崩溃 有时不会 我所做的就是启动它并等待数据 这是线程类 class ListenerThread QtCore QT
  • 如何在 PyQt 中使用 QThreads 双向设置信号和槽?

    这是基于 ekhumoro 答案的后续问题here https stackoverflow com a 52005755 4464653 and here https stackoverflow com a 20818401 4464653
  • 中断QThread睡眠

    我想知道如何暂停 QThread 然后在收到信号时恢复 我已阅读并知道我可以做这样的事情 def run self self ready False while not self ready self sleep 1 QtCore Slot

随机推荐

  • 基于Pytorch框架的目标检测迁移学习和微调训练自己的数据集

    目录 1 前置知识点 2 数据集准备 xff08 1 xff09 下载数据集 xff08 2 xff09 标注自己的数据集步骤 xff08 3 xff09 加载数据集 3 预训练模型进行修改 4 Pytorch中TensorBoard的使用
  • GAN原理及Pytorch框架实现GAN(比较容易理解)

    目录 1 初识GAN 什么是GAN xff1f GAN应用场景 2 GAN原理结构 xff08 1 xff09 生成对抗网络子网络 xff08 2 xff09 结构图 xff08 1 xff09 生成器 xff08 2 xff09 判别器
  • Windows下的CodeBlocks配置Opencv环境

    目录 1 Opencv下载 2 CodeBlocks下载 3 Cmake编译工具下载 4 编译Opencv源码 5 编译OpenCV库文件 xff08 1 xff09 方式一 xff08 2 xff09 方式二 6 动态链接库文件环境配置
  • Pytorch框架实现DCGAN(比较容易理解)

    目录 1 了解DCGAN 2 本文DCGAN网络模型结构 xff08 1 xff09 生成模型结构 xff08 2 xff09 判别模型结构 xff08 3 xff09 DCGAN模型结构 3 数据集下载 4 GAN代码实现 5 mainW
  • OpenCV的数据结构

    目录 1 各种类模板 xff08 1 xff09 二维点Point 类模板 xff08 2 xff09 三维点Point3 类模板 xff08 3 xff09 尺寸Size 类模板 xff08 4 xff09 矩形Rect 类模板 xff0
  • OpenCV下的Mat类模板基础(实例)

    目录 1 Mat类模板相关知识点 2 创建cv Mat类对象 3 cv Mat类对象基本操作 xff08 1 xff09 读取图像 显示图像 存储图像 Windows下的CodeBlocks配置Opencv环境 OpenCV的数据结构 1
  • OpenCV中Mat类模板的一些基本操作(实例)

    目录 1 操作图像像素 xff08 1 xff09 at方式访问图像像素 xff08 2 xff09 迭代器访问图像中像素 xff08 3 xff09 指针访问图像像素 xff08 4 xff09 整行整列像素值的赋值 Windows下的C
  • window平台搭建服务器

    在windows如何搭建服务器 xff1a 1 先打开控制面板 xff0c 然后打开程序和功能 xff0c 点击启用或者关闭windows功能 xff0c 找到Internet information services xff0c 选中后点
  • CycleGAN的基本原理以及Pytorch框架实现

    目录 1 了解CycleGAN xff08 1 xff09 什么是CycleGAN xff08 2 xff09 CycleGAN的应用场景 2 CycleGAN原理 xff08 1 xff09 整个模型 xff08 2 xff09 优化目标
  • OpenCV下的图形交互和媒体接口HighGUI

    目录 1 OpenCV下的GUI接口 xff08 1 xff09 回调函数 xff08 1 xff09 滑杆控件trackbars xff08 2 xff09 鼠标操作回调函数 xff08 3 xff09 键盘响应函数 Windows下的C
  • WGAN基本原理及Pytorch实现WGAN

    目录 1 WGAN产生背景 xff08 1 xff09 超参数敏感 xff08 2 xff09 模型崩塌 2 WGAN主要解决的问题 3 不同距离的度量方式 xff08 1 xff09 方式一 xff08 2 xff09 方式二 xff08
  • Pytorch框架实现WGAN-GP

    目录 1 WGAN GP产生背景 2 WGAN GP的主要成就 3 权重限制的困难 Difficulties with weight constraints xff08 1 xff09 WGAN GP算法流程 xff08 2 xff09 梯
  • Pytorch框架实现Pix2Pix(Image-to-image)

    目录 1 pix2pix研究背景 2 Pix2Pix基本原理 xff08 1 xff09 原理图 xff08 2 xff09 条件GAN cGAN xff08 3 xff09 公式原理 3 Pix2Pix网络模型 xff08 1 xff09
  • 【Microsoft COCO数据集介绍以及简单使用】

    Microsoft COCO数据集介绍以及简单使用 文前白话1 MSCOCO数据集介绍2 COCO数据集格式说明3 数据集下载4 COCO API pycocotools 其它的COCO API Reference 文前白话 本文介绍Mic
  • linux装SSH服务以及防止SSH暴力破解

    需要安装的包 xff1a openssh clients 6 6 1p1 22 el7 x86 64 openssh server 6 6 1p1 22 el7 x86 64 配置文件中常用参数的介绍 xff1a vim etc ssh s
  • 【Linux 切换 ES(elasticsearch)用户】

    Linux服务器里面有些操作不能用root用户操作ES xff0c 需要切换用户操作启动 1 切换用户命令 su 用户名 或者 ssh 用户名 64 服务器ip地址 su span class token operator span es
  • [DSA] 数字血管造影系统-硬件篇

    根据一下资料整理和增删 xff1a http www china radiology com showtopic 6451 aspx 2008年的资料 xff0c 但可以作为入门资料 xff0c 讲述了很多基本概念 http blog cs
  • QT修改QPushButton的背景色和文字颜色

    Qt中QPushButton背景颜色设置方法 不管我设置不是画笔颜色 xff0c 依然不管用 xff0c 一查才知道自己错了 因为在windows中QPushButton的颜色涉及到样式表 xff0c 所以应该设置样式表才可以 xff0c
  • anaconda释放空间

    学习内容 xff1a conda clean 后面可以跟很多超参 xff0c 不同超参有不同的功能 xff1a 可选参数 xff1a span class token operator span h span class token ope
  • Qt线程:QThread

    一 描述 一个QThread对象管理程序内的一个线程 xff0c QThreads在run 中开始执行 默认情况下 xff0c run 通过调用exec 启动事件循环 xff0c 并在线程内部运行一个Qt事件循环 可以通过使用 QObjec