前言
使用C++的std::thread写跨平台代码时,缺少一些像sdk里面线程一样的、丰富的功能接口,所以需要
对C++ std::thread进行封装拓展,使之支持线程延迟启动、支持线程挂起与恢复、支持一次性任务和循环任务、支持任何可变参调用对象。同时使用std::bind和 std::function替代采用子类继承重写run的方式。
一、核心代码
#include <thread>
#include <atomic>
#include <condition_variable>
#include <mutex>
class CXXThread
{
public:
//可调用对象及参数打包保存,延迟启动
template <typename F, typename... Args> explicit CXXThread(F &&f, Args &&...args)
{
std::function<decltype(f(args...))()> func = std::bind(std::forward<F>(f), std::forward<Args>(args)...);
m_func = [func]()
{
func();
};
m_bSuspend = true;
m_bStop = false;
}
/*
任务不带循环
*/
void StartOnce()
{
m_thread = std::thread(m_func);
}
void Join()
{
m_thread.join();
}
/*
任务带循环,支持线程挂起与退出
*/
void StartNoOnce()
{
m_thread = std::thread([this]() {
while (!m_bStop)
{
{
std::unique_lock<std::mutex> lock(m_mutex);
while (m_bSuspend)
{
m_cond.wait(lock);
}
}
if (m_bStop)//线程停止时如果是挂起状态,解除挂起状态后直接退出
{
break;
}
m_func();
}
m_bStop = false;
m_bSuspend = true;
});
}
//挂起
void Suspend()
{
std::unique_lock<std::mutex> lock(m_mutex);
m_bSuspend = true;
}
//恢复
void Resume()
{
{
std::unique_lock<std::mutex> lock(m_mutex);
m_bSuspend = false;
}
m_cond.notify_one();
}
//退出
void Stop()
{
if (m_bSuspend)
{
Resume();
}
m_bStop = true;
m_thread.join();
}
protected:
private:
std::thread m_thread;
std::function<void()> m_func;
std::atomic_bool m_bStop;
std::condition_variable m_cond;
std::mutex m_mutex;
std::atomic_bool m_bSuspend;
};
二、测试代码
#include <thread>
#include <atomic>
#include <condition_variable>
#include <mutex>
#include <windows.h>
int ts(int a, int b)
{
printf("%d===\n",a+b);
return a + b;
}
using ts_func = int(*)(int, int);
#define sleep(a) Sleep((a)*1000)
int main(int argc, char *argv[])
{
CXXThread th(ts, 1,1);
th.StartNoOnce();
sleep(5);
th.Resume();
sleep(5);
th.Suspend();
sleep(5);
th.Resume();
sleep(5);
th.Stop();
getchar();
return 0;
}
总结
代码已经测试,可以直接使用。采用C++11新特性,避免类的继承,适用范围广。
版权声明:本文为lizhen_14原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。