怎样建自己的网站免费的,网站的优点,万网可以花钱做网站吗,百度关键词排名优化原文链接#xff1a;C实现一个线程池 介绍
线程池是提高CPU利用率的一个非常高效的方法,线程池就是通过预先创建多个线程,当有任务时就执行,无任务时就阻塞.
相比一般的多线程方法,线程池更加简单,模块化,并且效率更高,因为不会重复创建删除线程.
预备知识
异步线程(包括f…原文链接C实现一个线程池 介绍
线程池是提高CPU利用率的一个非常高效的方法,线程池就是通过预先创建多个线程,当有任务时就执行,无任务时就阻塞.
相比一般的多线程方法,线程池更加简单,模块化,并且效率更高,因为不会重复创建删除线程.
预备知识
异步线程(包括future,packaged_task等对象): 创建异步返回的线程
wrapper装饰器(functionbind): 实现函数封装,泛型编程
condition_variable条件变量: 线程池任务分发和执行的条件控制
shared_ptr智能指针: 优化内存管理
类型推导和后置返回类型: 怎么实现泛型下正确返回未知类型
完美转发: 了解如何实现完美转发
线程池逻辑实现
#includeiostream
#includequeue
#includefunctional
#includecondition_variable
#includevector
#includethread
#includefuture
#includeatomicclass ThreadPools{
public:ThreadPools(int n_threads): stop(false){for(int i0;in_threads;i){workers.emplace_back([this](){// 每个线程构造函数while(true){int task;{ //锁的作用域std::unique_lockstd::mutex lock(this-mtx); //获取队列锁//判断队列非空或者线程池stop则返回.this-cv.wait(lock,[this](){return this-stop||!this-tasks.empty();});if(this-stopthis-tasks.empty()) return ;// 如果线程池stop且队列空,结束线程.taskthis-tasks.front();this-tasks.pop();}std::coutrun task: task\n;} });}};~ThreadPools(){{std::unique_lockstd::mutex lock(mtx);stoptrue;}cv.notify_all();//注意必须是 work引用参数形式, 线程不允许复制构造for(std::thread work: workers){ work.join();}std::coutthread pools final stop\n;};void enqueue(int task){{std::unique_lockstd::mutex lock(mtx);if(stop){std::coutpush to a stop pools\n;return ;}tasks.push(task);}std::coutpush task: task\n;cv.notify_one();return ;};private:std::vectorstd::thread workers;std::queueint tasks;std::condition_variable cv;std::mutex mtx;std::atomicbool stop;
};int main(){ThreadPools pools(2);for(int i0;i10;i) pools.enqueue(i);return 0;简单线程池
实现一个线程池,并执行三种任务: 有参无返回值任务,有参有返回值任务 和 有参返回消息结构体任务
#includethread
#includefunctional
#includefuture
#includecondition_variable
#includememory
#includeiostream
#includemutex
#includeatomic
#includevector
#includequeue
#includetype_traits
#includecstringclass ThreadPools{
public:ThreadPools(int n_threads): n_threads(n_threads),stop(false){for(int i0;in_threads;i){workers.emplace_back([this](){while(true){std::packaged_taskvoid() task;{std::unique_lockstd::mutex lock(this-mtx);this-cv.wait(lock,[this](){return this-stop || !this-tasks.empty();});if(this-stop this-tasks.empty()) return ;taskstd::move(this-tasks.front());this-tasks.pop();}task();//std::coutrun a task, current tasks sizetasks.size()\n;}});}}~ThreadPools(){{std::unique_lockstd::mutex lock(mtx);stoptrue;}cv.notify_all();for(std::thread worker : workers){worker.join();}//std::coutthread pools terminated\n;}templatetypename Fauto enqueue(F f)-std::futuretypename std::result_ofF()::type;private:int n_threads;std::atomicbool stop;std::vectorstd::thread workers;std::queuestd::packaged_taskvoid() tasks;std::condition_variable cv;std::mutex mtx;
};templatetypename F
auto ThreadPools::enqueue(F f)-std::futuretypename std::result_ofF()::type{using return_typetypename std::result_ofF()::type;auto taskstd::make_sharedstd::packaged_taskreturn_type()(std::forwardF(f));std::futurereturn_type restask-get_future();{std::unique_lockstd::mutex lock(mtx);if(stop){throw std::runtime_error(enqueue on stopped ThreadPool);}tasks.emplace([task](){(*task)();});}cv.notify_one();//std::coutpush a task, current tasks sizetasks.size()\n;return res;
}class Message{
public:Message(int fd,int from,int to,std::string content): fd(fd),from(from),to(to),content(content){sizecontent.size();}int fd;int from;int to;int size;std::string content;
};int main(){ThreadPools tp(3);// 无返回值任务for(int i0;i10;i){tp.enqueue([i](){std::couttask i\n;});}// 有返回值任务, 正常来讲,返回值是每回轮询,不是等待.std::vectorstd::futureint results;for(int i0;i10;i){auto f[](int i) { return i * i; };std::functionint() bfstd::bind(f,i);results.push_back(tp.enqueue(bf));}for(auto result: results){std::coutget resultresult.get()\n;}// 消息结构体作为返回值更常用std::vectorstd::futureMessage msgs;for(int i0;i10;i){auto f[](int i) { std::string ma message from:; mstd::to_string(i); Message msg(i,i,i,m); return msg;};std::functionMessage() bfstd::bind(f,i);msgs.push_back(tp.enqueue(bf));}for(auto msg: msgs){Message m(msg.get());std::coutget message: from:m.from to:m.to size:m.size content:m.content\n;}return 0;
}// task task 1
// task task 3
// 2task 4// task 5
// 0task 6// task 8
// task 9
// get resulttask 07// get result1
// get result4
// get result9
// get result16
// get result25
// get result36
// get result49
// get result64
// get result81
// get message: from:0 to:0 size:16 content:a message from:0
// get message: from:1 to:1 size:16 content:a message from:1
// get message: from:2 to:2 size:16 content:a message from:2
// get message: from:3 to:3 size:16 content:a message from:3
// get message: from:4 to:4 size:16 content:a message from:4
// get message: from:5 to:5 size:16 content:a message from:5
// get message: from:6 to:6 size:16 content:a message from:6
// get message: from:7 to:7 size:16 content:a message from:7
// get message: from:8 to:8 size:16 content:a message from:8
// get message: from:9 to:9 size:16 content:a message from:9