C++11中std::thread线程实现暂停(挂起)功能

目录
  • 一、封装Thread类
  • 二、测试代码

一、封装Thread类

我们基于C++11中与平台无关的线程类std::thread,封装Thread类,并提供start()、stop()、pause()、resume()线程控制方法。

为了让线程在暂停期间,处于休眠,不消耗CPU,我们使用C++11提供的锁和条件变量来实现。

  • std::mutex
  • std::condition_variable

Thread.h

#ifndef 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;
};

#endif // THREAD_H

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);

    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();
}

运行结果:

到此这篇关于C++11中std::thread线程实现暂停(挂起)功能的文章就介绍到这了,更多相关C++11 std::thread线程暂停内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++中std::thread线程用法

    目录 1:std::thread的基本用法 2:std:: thread常用的成员函数 3:建立新 thread执行类别中的函数 4:建立新 thread 执行 lambda expression 5:join等待thread执行结束 6:detach不等待 thread执行结束 7:std::thread 参数传递使用引用的方法 1:std::thread的基本用法 最简单的 std::thread用法如下,调用 thread将立即同时开始执行这个新建立的线程,新线程的任务执行完毕之后, ma

  • C++11 并发指南之std::thread 详解

    上一篇博客<C++11 并发指南一(C++11 多线程初探)>中只是提到了 std::thread 的基本用法,并给出了一个最简单的例子,本文将稍微详细地介绍 std::thread 的用法. std::thread 在 <thread> 头文件中声明,因此使用 std::thread 时需要包含 <thread> 头文件. std::thread 构造 default (1) thread() noexcept; initialization (2) template

  • c++11中关于std::thread的join的详解

    std::thread是c++11新引入的线程标准库,通过其可以方便的编写与平台无关的多线程程序,虽然对比针对平台来定制化多线程库会使性能达到最大,但是会丧失了可移植性,这样对比其他的高级语言,可谓是一个不足.终于在c++11承认多线程的标准,可谓可喜可贺!!! 在使用std::thread的时候,对创建的线程有两种操作:等待/分离,也就是join/detach操作.join()操作是在std::thread t(func)后"某个"合适的地方调用,其作用是回收对应创建的线程的资源,避

  • C++11并发编程:多线程std::thread

    一:概述 C++11引入了thread类,大大降低了多线程使用的复杂度,原先使用多线程只能用系统的API,无法解决跨平台问题,一套代码平台移植,对应多线程代码也必须要修改.现在在C++11中只需使用语言层面的thread可以解决这个问题. 所需头文件<thread> 二:构造函数 1.默认构造函数 thread() noexcept 一个空的std::thread执行对象 2.初始化构造函数 template<class Fn, class... Args> explicit th

  • C++ std::thread 使用方法

    目录 一.std::thread的构造和析构 二.std::thread的成员函数 三.线程间的通信 四.线程的异常处理 五.总结 总结: C++是一种高级编程语言,被广泛用于开发高性能.大规模.复杂的软件系统.其中一个强大的特性就是多线程编程,而std::thread是C++标准库提供的多线程支持的重要组成部分. std::thread是一个轻量级线程类,它允许程序员创建.启动.停止.等待线程.与其他多线程库不同,std::thread在运行时不需要显式地创建和销毁线程,而是通过构造和析构线程

  • C#中ManualResetEvent实现线程的暂停与恢复

    目录 背景 ManualResetEvent介绍 实现设计 背景 前些天遇到一个需求,在没有第三方源码的情况下,刷新一个第三方UI,并且拦截到其ajax请求的返回结果.当结果为AVALIABLE的时候,停止刷新并语音提示,否则继续刷新. 分析这个需求,发现需要控制一个刷新循环的暂停与开始,因此网上搜到了通过ManualResetEvent实现线程的暂停与恢复. ManualResetEvent介绍 ManualResetEvent是一个通过信号机制,实现线程间状态同步的类.常用的方法有以下三个:

  • C++11中std::declval的实现机制浅析

    本文主要给大家介绍了关于C++11中std::declval实现机制的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍: 在vs2013中,declval定义如下 template <_Ty> typenamea dd_rvalue_reference<_Ty>::type declval() _noexcept; 其中,add_rvalue_reference为一个traits,定义为 template <_Ty> struct add_rvalue_ref

  • C++11中std::move、std::forward、左右值引用、移动构造函数的测试问题

    关于C++11新特性之std::move.std::forward.左右值引用网上资料已经很多了,我主要针对测试性能做一个测试,梳理一下这些逻辑,首先,左值比较熟悉,右值就是临时变量,意味着使用一次就不会再被使用了.针对这两种值引入了左值引用和右值引用,以及引用折叠的概念. 1.右值引用的举例测试 #include <iostream> using namespace std; ​ //创建一个测试类 class A { public: A() : m_a(55) { } ​ int m_a;

  • c++11中std::move函数的使用

    C++11在运行期有所增强,通过增加核心的右值引用机制来改善临时对象导致的效率低下的问题.C++临时对象引入了多余的构造.析构及其内部资源的申请释放函数调用,导致程序运行时性能受损,这一点被广为诟病.C++标准委员会在C++11中引入了右值引用这个核心语言机制,来提升运行期性能 过std::move,可以避免不必要的拷贝操作. std::move是为性能而生. std::move是将对象的状态或者所有权从一个对象转移到另一个对象,只是转移,没有内存的搬迁或者内存拷贝. 变量表达式是一个左值,即使

  • C++11中std::function与std::bind的用法实例

    目录 关于std::function 的用法: 关于std::bind 的用法: 附:std::function与std::bind双剑合璧 总结 关于std::function 的用法: 其实就可以理解成函数指针 1. 保存自由函数 void printA(int a) { cout<<a<<endl; } std::function<void(int a)> func; func = printA; func(2); 保存lambda表达式 std::functio

  • C++11中std::future的具体使用方法

    C++11中的std::future是一个模板类.std::future提供了一种用于访问异步操作结果的机制.std::future所引用的共享状态不能与任何其它异步返回的对象共享(与std::shared_future相反)( std::future references shared state that is not shared with any other asynchronous return objects (as opposed to std::shared_future)).一

  • C++11中std::packaged_task的使用详解

    C++11中的std::packaged_task是个模板类.std::packaged_task包装任何可调用目标(函数.lambda表达式.bind表达式.函数对象)以便它可以被异步调用.它的返回值或抛出的异常被存储于能通过std::future对象访问的共享状态中. std::packaged_task类似于std::function,但是会自动将其结果传递给std::future对象. std::packaged_task对象内部包含两个元素:(1).存储的任务(stored task)

  • C++11中std::async的使用详解

    C++11中的std::async是个模板函数.std::async异步调用函数,在某个时候以Args作为参数(可变长参数)调用Fn,无需等待Fn执行完成就可返回,返回结果是个std::future对象.Fn返回的值可通过std::future对象的get成员函数获取.一旦完成Fn的执行,共享状态将包含Fn返回的值并ready. std::async有两个版本: 1.无需显示指定启动策略,自动选择,因此启动策略是不确定的,可能是std::launch::async,也可能是std::launch

  • 详解C++11中的线程锁和条件变量

    线程 std::thread类, 位于<thread>头文件,实现了线程操作.std::thread可以和普通函数和 lambda 表达式搭配使用.它还允许向线程的执行函数传递任意多参数. #include <thread> void func() { // do some work } int main() { std::thread t(func); t.join(); return 0; } 上面的例子中,t是一个线程实例,函数func()在该线程运行.调用join()函数是

随机推荐