赞
踩
目录
C++11提供了std::thread类,用于多线程编程。当构造一个std::thread对象时,线程就开始运行了,如:
std::thread* pMythread = new std::thread(threadFun, threadParm1, threadParm2, ....., threadParmN);
其中threadFun为线程的执行函数,可以是一般函数、类的成员函数、lamba表达式等, threadParm1, threadParm2, .... threadParamN为线程参数。更多关于std::thread的用法,请参见如下链接:
std::thread类中的所有方法中,都没有暂停、挂起及挂起后继续执行的方法,如何实现线程暂停、挂起、挂起后恢复执行?
现实中,经常会遇到需要线程暂时挂起,等某个条件符合后再继续运行。如:在有多个Tab页的窗体中,每个tab页开启了一个线程处理某个业务,但每次只有一个tab页为当前页,即用户在某一时刻只能面对一个tab页、处理一个tab页。如下:
上图界面说明如下:
为了提高CPU利用率,当用户在当前页面Tab1时,要将Tab2中的线程暂停;而当用户切换到Tab2即Tab2为当前页面时,要将Tab2中的线程恢复运行,且还要将要将Tab1中的线程暂停。
编写代码如下:
Thread.h
- #define THREAD_H
-
- #include <thread>
- #include <atomic>
- #include <mutex>
- #include <condition_variable>
-
- class Thread
- {
- public:
- Thread();
- virtual ~Thread();
-
- enum State
- {
- Stoped, ///<停止状态,包括从未启动过和启动后被停止
- Running, ///<运行状态
- Paused ///<暂停状态
- };
-
- State state() const;
-
- void start();
- void stop();
- void pause();
- void resume();
-
- protected:
- virtual void process() = 0;
-
- private:
- void run();
-
- private:
- std::thread* _thread;
- std::mutex _mutex;
- std::condition_variable _condition;
- std::atomic_bool _pauseFlag; ///<暂停标识
- std::atomic_bool _stopFlag; ///<停止标识
- State _state;
- };
Thread.cpp
- #include "Thread.h"
- #include <iostream>
-
- using namespace std;
-
- Thread::Thread()
- : _thread(nullptr),
- _pauseFlag(false),
- _stopFlag(false),
- _state(Stoped)
- {
-
- }
-
- Thread::~Thread()
- {
- stop();
- }
-
- Thread::State Thread::state() const
- {
- return _state;
- }
-
- void Thread::start()
- {
- if (_thread == nullptr)
- {
- _thread = new thread(&Thread::run, this);
- _pauseFlag = false;
- _stopFlag = false;
- _state = Running;
- }
- }
-
- void Thread::stop()
- {
- if (_thread != nullptr)
- {
- _pauseFlag = false;
- _stopFlag = true;
- _condition.notify_all(); // Notify one waiting thread, if there is one.
- _thread->join(); // wait for thread finished
- delete _thread;
- _thread = nullptr;
- _state = Stoped;
- }
- }
-
- void Thread::pause()
- {
- if (_thread != nullptr)
- {
- _pauseFlag = true;
- _state = Paused;
- }
- }
-
- void Thread::resume()
- {
- if (_thread != nullptr)
- {
- _pauseFlag = false;
- _condition.notify_all();
- _state = Running;
- }
- }
-
- void Thread::run()
- {
- cout << "enter thread:" << this_thread::get_id() << endl;
-
- while (!_stopFlag)
- {
- process();
- if (_pauseFlag)
- {
- unique_lock<mutex> locker(_mutex);
- while (_pauseFlag)
- {
- _condition.wait(locker); // Unlock _mutex and wait to be notified
- }
- locker.unlock();
- }
- }
- _pauseFlag = false;
- _stopFlag = false;
-
- cout << "exit thread:" << this_thread::get_id() << endl;
- }
main.cpp
- #include <QCoreApplication>
- #include <iostream>
- #include "Thread.h"
-
- using namespace std;
-
- void mySleep(int s)
- {
- std::this_thread::sleep_for(std::chrono::duration<double>(s));
- }
-
- class MyThread : public Thread
- {
- protected:
- virtual void process() override
- {
- cout << "do my something" << endl;
- mySleep(1);
- }
- };
-
- int main(int argc, char *argv[])
- {
- QCoreApplication a(argc, argv); // 采用Qt控制台程序测试
-
- MyThread thread;
-
- cout << "start thread" << endl;
- thread.start();
- cout << "thread state:" << thread.state() << endl;
- mySleep(3);
-
- cout << "pause thread" << endl;
- thread.pause();
- cout << "thread state:" << thread.state() << endl;
- mySleep(3);
-
- cout << "resume thread" << endl;
- thread.resume();
- cout << "thread state:" << thread.state() << endl;
- mySleep(3);
-
- cout << "stop thread" << endl;
- thread.stop();
- cout << "thread state:" << thread.state() << endl;
- mySleep(3);
-
- return a.exec();
- }
结果如下:
对于2节提到的需求例子,可以捕捉Tab页切换、改变事件,响应该事件,从而使相应的线程挂起或恢复执行。
对于run函数中的挂起代码如下:
- if (_pauseFlag)
- {
- unique_lock<mutex> locker(_mutex);
- while (_pauseFlag)
- {
- _condition.wait(locker); // Unlock _mutex and wait to be notified
- }
- locker.unlock();
- }
可否改为如下那样呢?
- if (_pauseFlag)
- {
- unique_lock<mutex> locker(_mutex);
- _condition.wait(locker); // Unlock _mutex and wait to be notified
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。