Linux_线程池(线程池实现计算任务)

1.线程池:

线程池: 一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着 监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利 用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。

2.C++实现简单的线程池实现计算任务

实现简单逻辑图:
在这里插入图片描述
线程池实现ThreadPool.h:

#pragma once 

#include<iostream>
#include<pthread.h>
#include<queue>

#define NUM 5

template<typename Task>
class ThreadPool
{
  private:
    std::queue<Task> _task_queue;//临界资源
    pthread_mutex_t _lock;
    int _thread_num;
    pthread_cond_t _cond;
  public:
   ThreadPool(int Num=NUM):_thread_num(Num){
     pthread_mutex_init(&_lock,nullptr);
     pthread_cond_init(&_cond,nullptr);
   }

   bool IsEmpty(){return _task_queue.empty();}

   static void*Routine(void*arg)//静态函数无隐含的this指针
   {
     pthread_detach(pthread_self());
     ThreadPool<Task>*self=(ThreadPool<Task>*)arg;
     while(true)
     {
       pthread_mutex_lock(&(self->_lock));
       while(self->IsEmpty())//循环检测临界资源是否就绪
       {
         //休眠
         pthread_cond_wait(&(self->_cond),&(self->_lock));
       }
       //任务队列有任务
       Task t;
       self->Pop(t);
       pthread_mutex_unlock(&(self->_lock));
       //解锁后处理任务
       t.Run();
     }
   }

   void Push(const Task&in)//外部添加任务
   {
     pthread_mutex_lock(&_lock);
     _task_queue.push(in);
     //唤醒一个线程
     pthread_cond_signal(&_cond);
     pthread_mutex_unlock(&_lock);
   }

   void Pop(Task&out)//线程获取任务
   {
     out=_task_queue.front();
     _task_queue.pop();
   }

   ~ThreadPool(){
     pthread_mutex_destroy(&_lock);
     pthread_cond_destroy(&_cond);
   }

   void InitThreadPool()
   {
     pthread_t tid;
     for(int i=0;i<_thread_num;i++)
     {
       pthread_create(&tid,nullptr,Routine,this);//为了避免传参时C++传this指针,在线程执行方法上带static。传参数时将this指针传到线程执行方法上。 
     }
     
   }
};

需要注意:线程处理函数要用静态成员函数。
因为:在线程处理函数中函数类型一定是void*(void*),如果是成员函数的话自带this指针,函数类型就发生了改变,要用静态成员函数无this指针,为了让线程处理函数能够访问到其他非静态成员函数,pthread_create函数的第四个参数将this指针传给线程处理函数上。

对于线程如何进行任务处理,只要任务类中自己定义了任务处理方法,在这里只要调用成员函数Run即可。

任务处理类,包含任务处理方法Run:Tesk.h

#include<map>
#include<functional>
#include<pthread.h>

class Task
{
  private:
    int x;int y;char op;
  public:
    Task()=default;
    Task(int _x,int _y,char _op):x(_x),y(_y),op(_op){}

    void Run()//计算任务处理方法
    {
      std::map<char,std::function<int(int,int)>>opMap=
      {
        {'+',[](int x,int y){return x+y;}},
        {'-',[](int x,int y){return x-y;}},
        {'*',[](int x,int y){return x*y;}},
        {'/',[](int x,int y){return x/y;}},
        {'%',[](int x,int y){return x%y;}}
      };

      double ret=(double)opMap[op](x,y);

      std::cout<<"Thread: ["<<pthread_self()<<"]: "<<x<<op<<y<<" "<<ret<<std::endl;
    }
};

主函数:

#include"Tesk.h"

#include"ThreadPool.h"

#include<ctime>

#include<cstdlib>

#include<unistd.h>

void TestPool()
{
  ThreadPool<Task>*t=new ThreadPool<Task>;
  t->InitThreadPool();
  srand((unsigned int)time(nullptr));
  const char*str="+-*/%";
  while(true)
  {
    int x=rand()%100+1;int y=rand()%100+1;
    Task task(x,y,str[rand()%5]);
    t->Push(task);
    sleep(1);
  }
}

int main()
{
  TestPool();
  return 0;
}

运行结果:
在这里插入图片描述

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NUC_Dodamce

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值