c++ 线程池

// 线程池线程个数缺省值
#include <iostream>
#include <vector>
#include <queue>
#include <unistd.h>
using namespace std;
const size_t NUM = 5;

template <class T>
class ThreadPool
{
public:
  // 构造函数,负责初始化成员变量和创建线程
  ThreadPool(const size_t num = NUM)
      : _threadNum(num), _tids(num)
  {
    pthread_mutex_init(&_lock, nullptr);
    pthread_cond_init(&_empty, nullptr);

    pthread_t id;
    for (size_t i = 0; i < _threadNum; ++i)
    {
      pthread_create(&id, nullptr, Routine, this);
      _tids[i] = id;
    }
  }

  // 析构函数中负责销毁互斥锁、条件变量和线程池中的线程
  ~ThreadPool()
  {
    pthread_mutex_destroy(&_lock);
    pthread_cond_destroy(&_empty);

    for (size_t i = 0; i < _threadNum; ++i)
    {
      pthread_cancel(_tids[i]);
    }
  }

  // 任务队列判空
  bool Empty()
  {
    return _taskQueue.empty();
  }

  // 申请任务队列的互斥锁
  void Lock()
  {
    pthread_mutex_lock(&_lock);
  }

  // 释放任务队列的互斥锁
  void UnLock()
  {
    pthread_mutex_unlock(&_lock);
  }

  // 任务队列为空时,线程在_empty条件变量下等待
  void Wait()
  {
    pthread_cond_wait(&_empty, &_lock);
  }

  // 唤醒一个在_empty下等待的线程
  void WakeUp()
  {
    pthread_cond_signal(&_empty);
  }

  // 外部调用该函数向任务队列中插入一个任务
  void Push(const T &task)
  {
    Lock();
    _taskQueue.push(task);
    UnLock();
    WakeUp();
  }

private:
  // 线程池中的线程调用该成员函数获得任务队列中的一个任务
  void Pop(T &task)
  {
    task = _taskQueue.front();
    _taskQueue.pop();
  }

  // 线程池中的线程执行该函数不断从任务队列中拿任务并解决任务
  static void *Routine(void *arg)
  {
    pthread_detach(pthread_self());
    ThreadPool *argThis = (ThreadPool *)arg;
    while (true)
    {
      argThis->Lock();
      while (argThis->Empty())
      {
        argThis->Wait();
      }
      T task;
      argThis->Pop(task);
      argThis->UnLock();

      task.Run();
    }
  }

  // 成员变量
  vector<pthread_t> _tids; // 记录池中所有线程的线程id
  size_t _threadNum;       // 记录线程池中线程的数量
  queue<T> _taskQueue;     // 任务队列,用于存储push进来的任务
  pthread_mutex_t _lock;   // 保证任务队列数据安全的互斥锁
  pthread_cond_t _empty;   // 队列为空时线程在该条件变量下等待
};

class Task
{
public:
  // 构造函数要求创建任务对象时显示传入相关数据
  Task(int x = 0, int y = 0, char op = 0)
      : _x(x), _y(y), _op(op)
  {
  }

  // 解决任务的Run函数
  void Run()
  {
    int ret = 0;
    switch (_op)
    {
    case '+':
      ret = _x + _y;
      break;

    case '-':
      ret = _x - _y;
      break;

    case '*':
      ret = _x * _y;
      break;

    case '/':
      if (_y == 0)
      {
        cerr << "div is error" << endl;
        return;
      }
      else
      {
        ret = _x / _y;
        break;
      }

    case '%':
      if (_y == 0)
      {
        cerr << "div is error" << endl;
        return;
      }
      else
      {
        ret = _x % _y;
        break;
      }

    default:
      cerr << "operation error" << endl;
      break;
    }
    cout << "Thread[" << pthread_self() << "]:" << _x << ' ' << _op << ' ' << _y << ' ' << '=' << ' ' << ret << endl;
  }

  // 运算数以及运算符
private:
  int _x;
  int _y;
  char _op;
};
int main()
{
  srand((size_t)time(nullptr));
  char opAll[5] = {'+', '-', '*', '/', '%'};
  // 创建一个任务类型为Task的线程池对象
  ThreadPool<Task> tp;
  // 不断地向线程池对象中派发任务,让里面的线程来解决这个任务
  while (true)
  {
    int x = rand() % 100 + 1;
    int y = rand() % 100 + 1;
    char op = opAll[rand() % 5];
    tp.Push(Task(x, y, op));
    sleep(1);
  }
  return 0;
}

效果

Thread[0x16f54b000]:93 + 8 = 101
Thread[0x16f3a7000]:58 % 35 = 23
Thread[0x16f433000]:36 / 37 = 0
Thread[0x16f4bf000]:77 + 2 = 79
Thread[0x16f31b000]:40 % 79 = 40
Thread[0x16f54b000]:36 * 37 = 1332
Thread[0x16f3a7000]:13 % 45 = 13
Thread[0x16f433000]:63 / 44 = 1
çThread[0x16f4bf000]:11 - 38 = -27
Thread[0x16f31b000]:54 / 6 = 9
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值