文章目录
ThreadPool.hpp
c
#pragma once
#include <vector>
#include <queue>
#include <iostream>
#include "Thread.hpp"
#include "LockGuard.hpp"
#define g_threadPool_num 5
template <class T>
class ThreadPool
{
public:
bool isEmpty()
{
return _task_queue.empty();
}
void waitCond()
{
pthread_cond_wait(&_cond, &_mtx);
}
T getTask()
{
T t = _task_queue.front();
_task_queue.pop();
return t;
}
public:
ThreadPool(int threadNum = g_threadPool_num)
: _threads(threadNum)
{
pthread_cond_init(&_cond, nullptr);
pthread_mutex_init(&_mtx, nullptr);
for (size_t i = 0; i < threadNum; i++)
{
_threads[i] = new Thread(routine, this, i + 1);
}
}
static void *routine(void *args)
{
ThreadData *td = (ThreadData *)args;
ThreadPool<T> *tp = (ThreadPool<T> *)td->_args;
while (true)
{
T task(-1);
{
LockGuard lock(&tp->_mtx);
while (tp->isEmpty())
{
tp->waitCond();
}
task = tp->getTask();
}
// 仿函数
task(td->_name);
}
return nullptr;
}
void pushTask(const T &task)
{
LockGuard lock(&_mtx);
_task_queue.push(task);
pthread_cond_signal(&_cond);
}
void run()
{
for (auto &e : _threads)
{
e->start();
}
}
~ThreadPool()
{
for (auto &e : _threads)
{
e->join();
}
pthread_cond_destroy(&_cond);
pthread_mutex_destroy(&_mtx);
}
private:
std::vector<Thread *> _threads;
std::queue<T> _task_queue;
pthread_mutex_t _mtx;
pthread_cond_t _cond;
};
Thread.hpp
c
#pragma once
#include <string>
#include <pthread.h>
#include <iostream>
typedef void *(*fun_t)(void *);
class ThreadData
{
public:
void *_args;
std::string _name;
pthread_t _tid;
fun_t _fun;
};
class Thread
{
public:
Thread(fun_t callback, void *args, int num)
{
char nameBuffer[64] = "Thread --- ";
sprintf(nameBuffer, "%s%d", nameBuffer, num);
_td._name = nameBuffer;
_td._args = args;
_td._fun = callback;
}
void start()
{
pthread_create(&_td._tid, nullptr, _td._fun, &_td);
}
void join()
{
pthread_join(_td._tid, nullptr);
}
public:
ThreadData _td;
};
LockGuard.hpp
c
#pragma once
#include <pthread.h>
class Mutex
{
public:
Mutex(pthread_mutex_t *mtx)
: _pmtx(mtx)
{
pthread_mutex_init(_pmtx, nullptr);
}
void lock()
{
pthread_mutex_lock(_pmtx);
}
void unlock()
{
pthread_mutex_unlock(_pmtx);
}
~Mutex()
{
pthread_mutex_destroy(_pmtx);
}
private:
pthread_mutex_t *_pmtx;
};
class LockGuard
{
public:
LockGuard(pthread_mutex_t *mtx)
: _mtx(mtx)
{
_mtx.lock();
}
~LockGuard()
{
_mtx.unlock();
}
private:
Mutex _mtx;
};
Task.hpp
c
#pragma once
#include <iostream>
class Task
{
public:
Task(int num)
: _num(num)
{
}
void operator()(const std::string &name)
{
std::cout << name << " 执行" << _num << "任务" << std::endl;
}
private:
int _num;
};
test.cc
c
#include "ThreadPool.hpp"
#include "Task.hpp"
#include <unistd.h>
int main()
{
ThreadPool<Task> tp;
tp.run();
int index = 0;
while (true)
{
Task t(index++);
tp.pushTask(t);
sleep(1);
}
return 0;
}