• 问题反馈可发送邮件到stubbornhuang@qq.com

  • 在本站开通年度VIP,无限制下载本站资源和阅读本站文章

  • 如果觉得本站的内容有帮助,可以考虑打赏博主哦!

  • 工资「喂饱肚子」,副业「养活灵魂」!

  • 本站由于前段时间遭受到大量临时和国外邮箱注册,所以对可注册的邮箱类型进行了限制!

  • 感谢大家访问本站,希望本站的内容可以帮助到大家!

  • 本站会放置Google广告用于维持域名以及网站服务器费用。

  • 计算机图形学与计算几何经典必备书单整理,下载链接可参考:https://www.stubbornhuang.com/1256/

  • 欢迎大家交换友链,可在https://www.stubbornhuang.com/申请友情链接进行友链交换申请!

C++11 – 封装std::thread,增加子线程启动、暂停、唤起、停止功能

C++ 发布于2021-10-21 阅读 11,473次 0次评论 8次点赞 本文共3539个字,阅读需要9分钟。

1 封装std::thread,增加子线程启动暂停、唤起、停止功能

C++标准库的std::thread已经为C++增加了很好的跨平台多线程编程体验,程序员只需要使用标准库std::thread就可以写出很好的多线程并发程序。但是在std::thread中对线程的控制需要自主控制。

我们经常会在子线程函数中写一个while循环去处理队列任务,当任务全部处理完成之后需要挂起线程,减少CPU负载,所以对应这个需求对std::thread进行了封装,实现一个扩展的std::thread基类,在基类中提供开启线程、暂停线程、唤起线程、停止线程的函数,并提供一个纯虚函数接口CustomRun,用于在子类中扩展自己的线程处理函数。

1.1 封装代码

代码如下:

ThreadExtension.h

#ifndef THREAD_EXTENSION_H
#define THREAD_EXTENSION_H

#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>

class ThreadExtension
{
    enum class ThreadState
    {
        Stoped = 0,
        Running = 1,
        Paused = 2
    };
public:
    ThreadExtension();
    virtual~ThreadExtension();

public:
    void StartThread();
    void PauseThread();
    void ResumeThread();
    void StopThread();

    int GetThreadState() const;

private:
    void Run();

protected:
    virtual void CustomRun() {};

private:
    ThreadState m_Thread_State;
    std::shared_ptr<std::thread> m_pThread;
    std::mutex m_Mutex;
    std::condition_variable m_Condition_Variable;
    std::atomic<bool> m_Thread_Pause_Flag;
    std::atomic<bool> m_Thread_Stop_Flag;

};

#endif // !THREAD_EXTENSION_H

ThreadExtension.cpp

#include "ThreadExtension.h"

ThreadExtension::ThreadExtension()
    :m_pThread(nullptr),
    m_Thread_Pause_Flag(false),
    m_Thread_Stop_Flag(false),
    m_Thread_State(ThreadState::Stoped)
{

}

ThreadExtension::~ThreadExtension()
{
    StopThread();
}

void ThreadExtension::StartThread()
{
    if (m_pThread == nullptr)
    {
        m_pThread = std::make_shared<std::thread>(&ThreadExtension::Run, this);

        if (m_pThread != nullptr)
        {
            m_Thread_Pause_Flag = false;
            m_Thread_Stop_Flag = false;
            m_Thread_State = ThreadState::Running;
        }
    }
}

void ThreadExtension::PauseThread()
{
    if (m_pThread != nullptr)
    {
        if (m_Thread_State == ThreadState::Running)
        {
            m_Thread_Pause_Flag = true;
            m_Thread_State = ThreadState::Paused;
        }
    }
}

void ThreadExtension::ResumeThread()
{
    if (m_pThread != nullptr)
    {
        if (m_Thread_State == ThreadState::Paused)
        {
            m_Thread_Pause_Flag = false;
            m_Condition_Variable.notify_all();
            m_Thread_State = ThreadState::Running;
        }
    }
}

void ThreadExtension::StopThread()
{
    if (m_pThread != nullptr)
    {
        m_Thread_Stop_Flag = true;
        m_Thread_Pause_Flag = false;    

        m_Condition_Variable.notify_all();

        if (m_pThread->joinable())
        {
            m_pThread->join();
        }

        // 释放
        m_pThread.reset();

        if (m_pThread == nullptr)
        {
            m_Thread_State = ThreadState::Stoped;
        }
    }
}

int ThreadExtension::GetThreadState() const
{
    return (int)m_Thread_State;
}

void ThreadExtension::Run()
{
    while (!m_Thread_Stop_Flag)
    {
        // 指定自定义线程操作
        try 
        {
            CustomRun();
        }
        catch (std::exception& e)
        {
            break;
        }

        // 暂停
        if (m_Thread_Pause_Flag)
        {
            std::unique_lock<std::mutex> thread_locker(m_Mutex);
            if (m_Thread_Pause_Flag)
            {
                // 等待互斥锁
                m_Condition_Variable.wait(thread_locker);
            }

            thread_locker.unlock();

        }
    }

    m_Thread_Pause_Flag = false;
    m_Thread_Stop_Flag = false;
}


在上述ThreadExtension类中,在StartThread函数中创建了一个以成员函数Run为线程函数的子线程,在Run函数中通过原子bool变量m_Thread_Stop_Flag控制线程函数开始或者停止,通过原子变量m_Thread_Pause_Flag控制线程函数暂停或者唤醒,在m_Thread_Pause_Flag为真时,使用std::condition_variable和std::mutex等待线程函数被重新唤醒继续执行。

1.2 使用示例

#include <iostream>

#include "ThreadExtension.h"

class TestThread :public ThreadExtension
{
public:
    TestThread()
    {

    }

    virtual ~TestThread()
    {

    }

    void CustomRun() override
    {
        std::cout << "CustomRun" << std::endl;
    }
};

int main()
{
    TestThread thread;
    std::cout << "Thread State:" << thread.GetThreadState() << std::endl;

    thread.StartThread();
    std::cout << "Thread State:" << thread.GetThreadState() << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(10));

    thread.PauseThread();
    std::cout << "Thread State:" << thread.GetThreadState() << std::endl;

    std::this_thread::sleep_for(std::chrono::milliseconds(11100));


    thread.ResumeThread();
    std::cout << "Thread State:" << thread.GetThreadState() << std::endl;

    std::this_thread::sleep_for(std::chrono::milliseconds(10));

    thread.StopThread();
    std::cout << "Thread State:" << thread.GetThreadState() << std::endl;

    getchar();

    return 0;
}

运行结果:

C++11 - 封装std::thread,增加子线程启动、暂停、唤起、停止功能-第0张图片

欢迎扫码关注我的微信公众号,及时获取文章更新

微信公众号二维码

本文作者:StubbornHuang

版权声明:本文为站长原创文章,如果转载请注明原文链接!

原文标题:C++11 – 封装std::thread,增加子线程启动、暂停、唤起、停止功能

原文链接:https://www.stubbornhuang.com/1766/

发布于:2021年10月21日 13:28:46

修改于:2023年06月26日 21:09:50

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

文章末尾
上一篇
资源分享 - Handbook of Digital Image Synthesis - Scientific Foundations of Rendering 英文PDF下载
计算几何与计算机图形学资源
下一篇
资源分享 - Image Content Retargeting - Maintaining Color, Tone, and Spatial Consistency 英文PDF下载
计算几何与计算机图形学资源
当前分类随机文章推荐

发表评论

您必须 [ 登录 ] 才能发表留言!

关注我们的公众号

微信公众号