Qt线程使用(开启、暂停、恢复、停止)

  • A+
所属分类:Qt专栏 Qt系列教程

Qt线程使用(开启、暂停、恢复、停止)

使用事件循环

开启线程

public:

volatile int i;

void ChannelThread::run()

{

qDebug()<<"run";

QTimer timer;

connect(&timer,SIGNAL(timeout()),this,SLOT(slotTimer()),Qt::DirectConnection);

timer.start(1000);

exec();

return;

}

void ChannelThread::slotTimer()

{

qDebug()<<i<<currentThreadId();

i++;

}

QTimer在线程中定义、关联并启动,因此,整个QTimer依附于子线程,采用直连方式Qt::DirectConnection指的是让slotTimer()在信号发送方所依附的线程中执行,如果选择队列方式,则由于this在主线程中定义将依附于主线程,这样,槽函数也将在主线程中执行。定时器的运行需要依赖于事件循环,因此,子线程中的事件循环未开启,则及时定时器start了,也不会执行槽函数。exec()即开启子线程的事件循环,exec()内部其实就是一个死循环,不断处理接收到的事件。

结束线程

channel->quit();

channel->wait();

delete channel;

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

不使用事件循环

开启线程

void ChannelThread::run()

{

qDebug()<<"run";

int i=0;

while (!isInterruptionRequested()) {

QMutexLocker lock(&m_lock);

qDebug()<<i;

i++;

msleep(1000);

}

return;

}

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

暂停线程

void ChannelThread::stop()

{

m_lock.lock();

}

首先在头文件中定义锁:QMutex m_lock,然后m_lock.lock();语句用于获取锁,不一定会在调用stop方法的时候立即暂停线程,可能是稍后暂停线程,这主要取决于何时调用stop方法的线程取得该锁。取得该锁后,循环的子线程将因为得不到锁而处于暂停状态。

继续线程

void ChannelThread::resume()

{

m_lock.unlock();

}

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

结束线程

channel->requestInterruption();

channel->wait();

delete channel;

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

 

 

Qt大课堂-QtShare

发表评论

您必须登录才能发表评论!