QT知识点总结—QThread

QT知识点总结——QThread

QThread类提供了一个与平台无关的方式来管理线程。

一个QThread对象管理程序里的一个线程。当QThread对象执行run()后它管理的线程开始运行。默认情况下,run()函数通过调用
exec()函数启动该线程的事件循环。

QThread有两种用法:

  • 使用QObject::moveToThread()将一个工作对象加入到某个线程中。
  • 在QThread子类中重新实现run()函数。

QThread用法一:使用QObject::moveToThread()将一个工作对象加入到某个线程中

你可以通过使用QObject::moveToThread()来将一个工作对象加入到某个线程中。

代码实例:

// QThread用法一:使用QObject::moveToThread()将一个工作对象加入到某个线程中
//
// 工作对象类
class Worker : public QObject
{
    Q_OBJECT

public slots:
    void doWork(const QString &parameter) {
        QString result;
        /* ... here is the expensive or blocking operation ... */
        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用法二:在QThread子类中重新实现run()函数

另外一种让代码在独立的线程中运行的方法,是在QThread子类中重新实现run()函数。

代码实例:

class WorkerThread : public QThread
{
    Q_OBJECT
    void run() override {
        QString result;
        /* ... here is the expensive or blocking operation ... */
        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的所有队列插槽都将在旧线程中执行。因此,希望调用新线程中的插槽的开发人员必须使用worker-object方法(参考本文QThread用法一);新插槽不应该直接实现到QThread子类中。

当子类化QThread时,请记住构造函数在旧线程中执行,而run()在新线程中执行。如果这两个函数访问同一个成员变量,属于从两个不同的线程访问该变量,要检查这样的操作是否线程安全。

注意:在跨线程的对象交互时必须小心。有关详细信息,请参见同步线程(Synchronizing Threads)。


管理线程

当线程started()和finished()时,QThread将发送一个信号通知你,你或者也可以用isFinished()和isRunning()来查询线程的状态。

你可以通过调用exit()或quit()来停止线程。在极端情况下,你可能希望强制terminate()一个正在执行的线程。然而,这样做是危险的,有关详细信息,请参阅terminate()和setTerminationEnabled()的文档。

从Qt 4.8开始,通过将finished()信号连接到QObject::deleteLater(),但线程运行结束时,会自动释放线程中定义的对象。

线程调用wait()可以阻塞本身,直到其它线程完成执行(或者超过指定的时间)。

QThread还提供了与平台无关的静态睡眠函数:sleep()、msleep()和usleep(),它们分别支持完整的秒、毫秒和微秒单位级别精度。这些函数在Qt 5.0中是公开的。

注意:因为Qt是一个事件驱动的框架,wait()和sleep()函数通常是不必要的。可以考虑用finished()信号来代替wait()函数,用QTimer类替代sleep()函数。

静态函数currentThreadId()和currentThread()返回当前执行线程的标识符。前者返回值是与平台相关的线程ID;后者是一个QThread指针。

你可以在启动线程之前,通过调用setObjectName()来设置线程名(如Linux的命令ps -L显示的)。如果没有调用setObjectName(),线程默认名是线程的类名。请注意,Windows的Release版本中目前还不支持。

枚举变量

enum QThread::Priority 这个枚举变量指明了操作系统如何调度新建立的线程


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用Qt的QProcess类杀掉一个QThread进程,你可以使用QProcess的start方法来启动一个进程,然后使用taskkill命令来杀掉指定的进程。在引用中的代码示例中,killExe函数展示了如何使用QProcess来杀掉一个指定的进程。在该函数中,通过执行命令"taskkill -im exeName -f"来杀掉进程。其中,exeName是要被杀掉的进程名。注意,这段代码是适用于Windows操作系统的。如果你使用的是Linux系统,你可以参考引用中的start函数的代码,然后自行编写适用于Linux系统的进程杀死代码。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【Qt专栏】Qt嵌入进程和杀死进程](https://blog.csdn.net/weixin_43729127/article/details/126908645)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [Qt进程和线程QProcess和QThread](https://blog.csdn.net/qq_45698138/article/details/126273572)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值