Qt线程的启动、暂停、继续、退出

本文详细介绍了Qt中线程的启动、暂停、继续及结束的控制机制,包括使用isInterruptionRequested()和m_mutex锁进行线程状态管理的具体实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.启动

void run(){
    while (!thread->isInterruptionRequested()) {
	QMutexLocker lock(&m_mutex);

	// to do something

	msleep(200);
    }
}

采用isInterruptionRequested()方法控制线程是否停止,该方法只有qt5才具备;采用锁m_mutex来决定线程是否暂停。用一个while循环使子线程一直处于运行状态。

如果该线程上运行的任务应该停止,则返回true。可以通过requestinterrupt()请求中断。

此函数可用于使长时间运行的任务完全可中断。不检查或操作这个函数返回的值是安全的,但是建议在长时间运行的函数中定期这样做。注意不要过于频繁地调用它,以保持较低的开销。

2.暂停

void pause() 
{
    m_mutex.lock();
}

m_mutex.lock();语句用于获取锁,不一定会在调用pause方法的时候立即暂停线程,可能是稍后暂停线程,这主要取决于何时调用pause方法的线程取得该锁。取得该锁后,循环的子线程将因为得不到锁而处于暂停状态。

3.继续

void resume()
{
    m_mutex.unlock();
}

调用resume()方法的线程释放锁,循环中的子线程将因为获得锁而继续循环运行。

4.结束线程

void exitThread()
{
    thread->requestInterruption();

    thread->wait();

    delete thread;
}

//结束线程

//thread->quit();

//thread->wait();

//delete thread;

//调用quit方法结束事件循环,即退出了exec()这个死循环,这样,就可以执行run方法中的return方法了,退出run。调用wait();方法是为了确保子线程退出了,已防止在未完全停止子线程的情况下delete而引发crash。

调用requestInterruption方法去请求停止线程,requestInterruption的实现机制实际上是通过互斥锁+标识变量的方式来实现的,通过维护标示变量来指定线程是否运行,循环的子线程将通过isInterruptionRequested()方法判断是否接收到暂停请求,如果接收到,则退出循环,也就意味着线程结束了。但线程的结束并不是立刻进行的,可能是稍后发生的,如果在线程还未停止前调用了delete方法,会引发crash,所以,在delete之前加一句wait();这句话的意思是等待线程完全停止,然后再去delete。

Qt中,线程暂停和等待信号再启动可以通过多种方式实现。以下是几种常见的方法: 1. **使用QThread和信号槽机制**: - 创建一个继承自QThread的类。 - 在该类中定义一个槽函数用于暂停线程。 - 使用QWaitCondition和QMutex来实现线程暂停和唤醒。 ```cpp #include <QThread> #include <QWaitCondition> #include <QMutex> class MyThread : public QThread { Q_OBJECT public: MyThread(QObject *parent = nullptr) : QThread(parent), m_paused(false) {} protected: void run() override { while (!isInterruptionRequested()) { { QMutexLocker locker(&m_mutex); if (m_paused) { m_waitCondition.wait(&m_mutex); } } // 线程的工作代码 // ... // 模拟一些工作 QThread::sleep(1); } } public slots: void pause() { QMutexLocker locker(&m_mutex); m_paused = true; } void resume() { QMutexLocker locker(&m_mutex); m_paused = false; m_waitCondition.wakeAll(); } private: QMutex m_mutex; QWaitCondition m_waitCondition; bool m_paused; }; ``` 2. **使用QEventLoop和信号槽机制**: - 在线程的工作函数中使用QEventLoop。 - 通过信号槽机制控制QEventLoop的退出,从而实现线程暂停和恢复。 ```cpp #include <QThread> #include <QEventLoop> class MyThread : public QThread { Q_OBJECT public: MyThread(QObject *parent = nullptr) : QThread(parent), m_paused(false) {} protected: void run() override { QEventLoop loop; connect(this, &MyThread::resumeSignal, &loop, &QEventLoop::quit); while (!isInterruptionRequested()) { if (m_paused) { loop.exec(); } // 线程的工作代码 // ... // 模拟一些工作 QThread::sleep(1); } } public slots: void pause() { m_paused = true; } void resume() { m_paused = false; emit resumeSignal(); } signals: void resumeSignal(); private: bool m_paused; }; ``` 3. **使用QSemaphore**: - 使用QSemaphore来控制线程暂停和恢复。 ```cpp #include <QThread> #include <QSemaphore> class MyThread : public QThread { Q_OBJECT public: MyThread(QObject *parent = nullptr) : QThread(parent), m_semaphore(0) {} protected: void run() override { while (!isInterruptionRequested()) { m_semaphore.acquire(); // 线程的工作代码 // ... // 模拟一些工作 QThread::sleep(1); } } public slots: void pause() { m_semaphore.acquire(); } void resume() { m_semaphore.release(); } private: QSemaphore m_semaphore; }; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凌武贰玖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值