threadPool.h
#ifndef _THREADPOOL_H
#define _THREADPOOL_H
#include <iostream>
#include <pthread.h>
#include <queue>
#include <unistd.h>
#define THREAD_NUM 5
#define MAX_TASK_NUM 10000
class Task
{
public:
virtual void execute() = 0;
virtual ~Task(){};
};
class ThreadPool
{
private:
bool tStop; // 线程停止标识
int tNumThreads; // 初始化时设定的线程池中线程的个数
int tNumTask; // 允许任务队列中的最大任务数
pthread_t *tThreads; // 描述线程池的数组,其大小为 numThreads
std::queue<Task *> tTaskQueue; // 任务队列
pthread_mutex_t tQueueMutex; // 保护任务队列的互斥锁
pthread_cond_t tQueueCond; // 唤醒线程的条件变量
/* 工作线程运行的函数,它不断从工作队列中取出任务并执行 */
static void *workerThread(void *arg);
void run();
void cleanUp();
void stop();
public:
ThreadPool(int threadNum = THREAD_NUM, int taskNum = MAX_TASK_NUM);
~ThreadPool();
/* 往请求队列中添加任务 */
void addTask(Task *task);
};
#endif
threadPool.cpp
#include "threadPool.h"
ThreadPool::ThreadPool(int threadNum, int taskNum)
: tStop(false), tNumThreads(threadNum), tNumTask(taskNum), tThreads(nullptr)
{
if (threadNum <= 0 || taskNum <= 0)
{
// 如果传入的线程数量或最大任务数了小于等于0,则抛出异常
throw std::exception();
}
if (pthread_mutex_init(&tQueueMutex, nullptr) != 0)
{
throw std::exception();
}
if (pthread_cond_init(&tQueueCond, nullptr) != 0)
{
pthread_mutex_destroy(&tQueueMutex); // 销毁已初始化的互斥锁
throw std::exception();
}
tThreads = new pthread_t[threadNum];
if (!tThreads)
{
// 申请空间失败,抛出异常
throw std::bad_alloc();
}
/* 创建 thread_number 个线程,并将它们都设置为分离线程 */
for (int i = 0; i < threadNum; ++i)
{
if (pthread_create(&tThreads[i], nullptr, workerThread, this) != 0)
{
cleanUp();
throw std::exception();
}
}
}
ThreadPool::~ThreadPool()
{
stop();
cleanUp();
}
void ThreadPool::stop()
{
tStop = true;
pthread_cond_broadcast(&tQueueCond);
}
void ThreadPool::cleanUp()
{
for (int i = 0; i < tNumThreads; ++i)
{
pthread_join(tThreads[i], nullptr);
}
delete[] tThreads;
pthread_mutex_destroy(&tQueueMutex);
pthread_cond_destroy(&tQueueCond);
}
void ThreadPool::addTask(Task *task)
{
pthread_mutex_lock(&tQueueMutex);
while (tTaskQueue.size() > tNumTask)
{
pthread_cond_wait(&tQueueCond, &tQueueMutex);
}
tTaskQueue.push(task);
pthread_mutex_unlock(&tQueueMutex);
pthread_cond_signal(&tQueueCond);
}
void *ThreadPool::workerThread(void *arg)
{
ThreadPool *pool = static_cast<ThreadPool *>(arg);
pool->run();
return nullptr;
}
void ThreadPool::run()
{
while (true)
{
pthread_mutex_lock(&tQueueMutex);
while (tTaskQueue.empty() && !tStop)
{
pthread_cond_wait(&tQueueCond, &tQueueMutex);
}
if (tTaskQueue.empty() && tStop)
{
pthread_mutex_unlock(&tQueueMutex);
break; // Exit the thread when stopping
}
Task *task = tTaskQueue.front();
tTaskQueue.pop();
pthread_mutex_unlock(&tQueueMutex);
task->execute();
pthread_cond_signal(&tQueueCond); // Notify waiting threads
}
}
test.cpp
#include "threadPool.h"
using namespace std;
class MyTask : public Task
{
public:
void execute()
{
cout << pthread_self() << endl;
// 执行任务
// 需手动释放
delete this;
}
private:
int id;
};
int main()
{
ThreadPool *pool = new ThreadPool(5, 10000);
for (int i = 0; i < 100; i++)
{
MyTask *task = new MyTask;
pool->addTask(task);
}
getchar();
return 0;
}