灰色行业网站,网站建设属于哪类税率,汕头市建设工程信息网,旅游型网站的建设背景图片一、线程池 一种线程使用模式。线程过多会带来调度开销#xff0c;进而影响缓存局部性和整体性能。而线程池维护着多个线程#xff0c;等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用#xff0c…一、线程池 一种线程使用模式。线程过多会带来调度开销进而影响缓存局部性和整体性能。而线程池维护着多个线程等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。
二、线程池的应用场景
1. 需要大量的线程来完成任务且完成任务的时间比较短。WEB服务器完成网页请求这样的任务使用线程池技术是非常合适的。因为单个任务小而任务数量巨大你可以想象一个热门网站的点击次数。但对于长时间的任务比如一个 Telnet连接请求线程池的优点就不明显了。因为Telnet会话时间比线程的创建时间大多了。 2. 对性能要求苛刻的应用比如要求服务器迅速响应客户请求。 3. 接受突发性的大量请求但不至于使服务器因此产生大量线程的应用。突发性大量客户请求在没有线程池情况下将产生大量线程虽然理论上大部分操作系统线程数目最大值不是问题短时间内产生大量线程可能使内存到达极限出现错误. 4.线程池示例: 1. 创建固定数量线程池循环从任务队列中获取任务对象 2. 获取到任务对象后执行任务对象中的任务接口. 三、代码
主线程发布任务多线程获得任务执行任务
(1)任务
Task.hpp#pragma once
#include iostream
#include stringstd::string opers-*/%;enum{DivZero1,ModZero,Unknown
};class Task
{
public:Task(int x, int y, char op) : data1_(x), data2_(y), oper_(op), result_(0), exitcode_(0){}void run(){switch (oper_){case :result_ data1_ data2_;break;case -:result_ data1_ - data2_;break;case *:result_ data1_ * data2_;break;case /:{if(data2_ 0) exitcode_ DivZero;else result_ data1_ / data2_;}break;case %:{if(data2_ 0) exitcode_ ModZero;else result_ data1_ % data2_;} break;default:exitcode_ Unknown;break;}}void operator ()(){run();}std::string GetResult(){std::string r std::to_string(data1_);r oper_;r std::to_string(data2_);r ;r std::to_string(result_);r [code: ;r std::to_string(exitcode_);r ];return r;}std::string GetTask(){std::string r std::to_string(data1_);r oper_;r std::to_string(data2_);r ?;return r;}~Task(){}private:int data1_;int data2_;char oper_;int result_;int exitcode_;
};
2线程池
#pragma once
#include iostream
#includevector
#includestring
#includepthread.h
#includequeue
struct ThreadInfo
{pthread_t tid;std::string name;
};
static const int deafultnum5; //默认多少个线程
template class T
class ThreadPool
{
public:void Lock(){pthread_mutex_lock(mutex_);}void Unlock(){pthread_mutex_unlock(mutex_);}void Wakeup()//线程唤醒{pthread_cond_signal(cond_);}void ThreadSleep() //线程休眠{pthread_cond_wait(cond_, mutex_);}bool IsQueueEmpty(){return tasks_.empty();}std::string GetThreadName(pthread_t tid){for (const auto ti : threads_){if (ti.tid tid)return ti.name;}return None;}
public:ThreadPool(int numdeafultnum):threads_(num){pthread_mutex_init(mutex_,nullptr);pthread_cond_init(cond_,nullptr);}static void *HandleTask(void *args) //所有线程启动后就会去检测有没有任务有任务就执行没任务就休眠{ThreadPoolT *tpstatic_castThreadPoolT*(args);std::string nametp-GetThreadName(pthread_self());while (true){tp-Lock();while(tp-IsQueueEmpty()){tp-ThreadSleep();}T ttp-pop();tp-Unlock();//当你拿到这个任务这个任务就是属于你你不需要在加锁解锁之间。t();std::coutnamerun,result:t.GetResult()std::endl;}}void start(){int numthreads_.size();for(int i0;inum;i){threads_[i].namethread-std::to_string(i1);pthread_create((threads_[i].tid),nullptr,HandleTask,this);}}T pop(){T ttasks_.front();tasks_.pop();return t;}void push(const T t)//往线程池中放任务之后线程才能执行任务{Lock();tasks_.push(t); //有任务线程别睡了Wakeup();Unlock();}~ThreadPool(){pthread_mutex_destroy(mutex_);pthread_cond_destroy(cond_);}
private:std::vectorThreadInfo threads_; //这是个vector容器表示有多少个线程std::queueT tasks_;pthread_mutex_t mutex_;pthread_cond_t cond_;
}; 3主函数
#include iostream
#include ThreadPool.hpp
#include Task.hpp
#include unistd.h
int main()
{ThreadPoolTask *tpnew ThreadPoolTask(5);tp-start();srand(time(nullptr) ^ getpid());while(true){//1.构建任务int x rand() % 10 1;usleep(10);int y rand() % 5;char op opers[rand()%opers.size()];Task t(x, y, op);tp-push(t);//ThreadPoolTask::GetInstance()-Push(t);//2.交给线程池处理std::cout main thread make task: t.GetTask() std::endl;sleep(1);}
}
4执行结果