QT多线程(主动挂起线程)
  micz61TEX78l 2023年11月02日 43 0

(文章目录)


前言

本篇文章来讲解一下QT中如何主动挂起线程,在不想让一个线程运行的时候我们应该如何让线程挂起呢?我们都知道使用sleep函数可以让线程挂起一段时间,但是一段时间过后线程又继续运行,那么有什么方法可以让线程在特定条件下挂起,特定条件下运行吗?

一、线程的挂起态

在Qt中,线程可以通过调用 QThread::sleep() 函数进入挂起状态。QThread::sleep() 函数会导致线程在指定的毫秒数内休眠,进入睡眠状态,等待指定的时间后再继续运行。

线程的挂起状态常用于等待某个事件的发生,比如等待信号的到来、等待定时器的触发、等待文件的读写操作完成等。当线程挂起时,它会主动放弃 CPU 的时间片,以节约系统资源。

在Qt中,还可以通过将线程阻塞在某个对象上来实现挂起状态。比如,可以通过调用 QWaitCondition::wait() 函数将线程阻塞在某个条件变量上,等待其他线程对该条件变量发出信号后再继续执行。

需要注意的是,线程在挂起状态下不会停止,仍然会占用系统资源。因此,在使用线程挂起功能时,需要确保挂起的时间不会过长,以避免降低系统的性能和可靠性。

此外,需要注意线程挂起状态的使用场景和时机。线程挂起过程中不会处理任何事件,包括定时器事件、键盘事件、鼠标事件等,因此,如果在线程中进行长时间的阻塞或挂起,可能会导致 UI 界面无响应,影响用户体验。因此,建议在非必要情况下尽量避免使用线程挂起功能,或者通过线程间通信等机制来替代线程挂起。

二、QWaitCondition

在Qt中,QWaitCondition 是一个用于线程同步的对象,它可以让一个线程等待或者阻塞在一个特定的条件上,直到被其他线程唤醒。

QWaitCondition 的使用通常涉及以下三个对象:

条件变量(QWaitCondition),用来等待和唤醒线程。

互斥锁(QMutex),用来保护条件变量。

通知对象(QMutexLocker),用来通知和等待。

使用 QWaitCondition 时需要注意以下几点:

线程只有在持有相应的互斥锁时才能调用 QWaitCondition::wait() 函数;在阻塞期间会释放互斥锁并进入挂起状态。

发送信号之前,必须先获取相应的互斥锁,否则线程不会得到通知。

通过调用 QWaitCondition::wakeOne() 可以唤醒单个线程,调用 QWaitCondition::wakeAll() 可以唤醒所有等待的线程。

等待时,建议使用 while 循环来检查条件是否满足,防止条件非常容易发生变化的情况下出现误唤醒的问题。

三、示例代码

这段程序主要是实现了主线程既可以唤醒ThreadA线程又可以将ThreadA线程挂起的功能。

#include <QtCore/QCoreApplication>
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
#include <QDebug>

QMutex g_mutex;
QWaitCondition g_waitcondition;
bool ConditionMet = true;

class ThreadA : public QThread
{
protected:
    void run()
    {
        qDebug() << "Thread Begin";
        while(1)
        {
            g_mutex.lock();            
            while(!ConditionMet)
            {
                g_waitcondition.wait(&g_mutex);//先释放锁,再获取锁
                break;
            }
            qDebug() << "ThreadA";
            g_mutex.unlock();
            sleep(1);
        }
        qDebug() << "Thread End";
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    ThreadA t1;
    t1.start();

    int i = 0;

    while(1)
    {
        qDebug() << "Main Thread";
        i++;
        if(i == 5)
        {
            qDebug() << "ThreadA stop";
            g_mutex.lock();
            ConditionMet = false;
            g_mutex.unlock();
        }
        else if(i == 10)
        {
            qDebug() << "wake ThreadA";
            i = 0;
            g_mutex.lock();
            ConditionMet = true;
            g_waitcondition.wakeOne();
            g_mutex.unlock();
        }
        QThread::sleep(1);
    }

    return a.exec();
}

总结

QWaitCondition 在多线程编程中具有重要的作用,可以帮助实现线程之间的同步和通信,也是Qt中高效使用多线程的关键。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  HE3leaVn7jMN   2023年11月24日   28   0   0 Timei++#include
  HE3leaVn7jMN   2023年11月26日   28   0   0 i++#include
micz61TEX78l