基于 linux 的简单线程池实现
参考:
https://www.cnblogs.com/venow/archive/2012/11/22/2779667.html
https://blog.csdn.net/kankan231/article/details/24499947/
构思阶段:
1. 线程池的概念:
线程池的实现原理是这样的:在应用程序启动之后,就马上创建一定数量的线程,放入空闲的队列中。这些线程都是处于阻塞状态,这些线程只占一点内存,不占用CPU。当任务到来后,线程池将选择一个空闲的线程,将任务传入此线程中运行。当所有的线程都处在处理任务的时候,线程池将自动创建一定的数量的新线程,用于处理更多的任务。执行任务完成之后线程并不退出,而是继续在线程池中等待下一次任务。当大部分线程处于阻塞状态时,线程池将自动销毁一部分的线程,回收系统资源。
2. 线程池的工作机制
2.1 在线程池的编程模式下,任务是提交给整个线程池,而不是直接提交给某个线程,线程池在拿到任务后,就在内部寻找是否有空闲的线程,如果有,则将任务交给某个空闲的线程。
2.2 一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务。
2.3 如果所有的线程都处于工作状态,就添加到队列,进行排队。
2.4 如果队列中的任务个数大于队列的所能容纳的最大数量,那就不能添加任务到队列中,只能等待队列不满才能添加任务到队列中。
代码:
//threadpool.h #ifndef THREADPOOL_H #define THREADPOOL_H #include<iostream> #include<pthread.h> #include<cstdlib> #include<cassert> #include<cstdio> #include<deque> using namespace std; struct Job { void* (*doJobFun)(void *arg); //线程回调函数 void *arg; //回调函数参数 }; class ThreadPool { unsigned int threadNum; //线程池中开启线程的个数 unsigned int maxJobNum; //队列中最大job的个数 deque<Job> jobQueue; //任务队列 pthread_t *pthreads; //线程池中所有线程的pthread_t pthread_mutex_t mutex; //互斥信号量 pthread_cond_t condQueueEmpty; //队列为空的条件变量 pthread_cond_t condQueueFull; //队列为满的条件变量 bool isPoolClose; //线程池是否已经关闭 public: ThreadPool(int threadNum=10, int maxJobNum=100); int addJob(Job job); int destroy(); ~ThreadPool(); friend void* run(void* arg); }; #endif
//threadpool.cpp #include"threadpool.h" void* run(void* arg) { ThreadPool *pool = (ThreadPool *)arg; struct Job job ; while (1) //死循环 { pthread_mutex_lock(&(pool->mutex)); if (pool->isPoolClose) //线程池关闭,线程就退出 { pthread_mutex_unlock(&(pool->mutex)); pthread_exit(NULL); } while ((pool->jobQueue.empty())) //队列为空时,就等待队列非空 { //printf("job queue is empty.....\n"); pthread_cond_wait(&(pool->condQueueEmpty), &(pool->mutex)); if (pool->isPoolClose) //线程池关闭,线程就退出 { pthread_mutex_unlock(&(pool->mutex)); pthread_exit(NULL); } } job=pool->jobQueue.front(); pool->jobQueue.pop_front(); //printf("get job %d,size:%d\n",(int)job.arg,pool->jobQueue.size()); if (pool->jobQueue.size() == (pool->maxJobNum-1)) { pthread_cond_broadcast(&(pool->condQueueFull)); //队列非满,就可以通知threadpool_add_job函数,添加新任务 } pthread_mutex_unlock(&(pool->mutex)); (*(job.doJobFun))(job.arg); //线程真正要做的工作,回调函数的调用 } } ThreadPool::ThreadPool(int threadNum, int maxJobNum) { this->threadNum = threadNum; this->maxJobNum = maxJobNum; if (pthread_mutex_init(&(this->mutex), NULL)) { perror("pthread_mutex_init"); exit(1); } if (pthread_cond_init(&(this->condQueueEmpty), NULL)) { perror("pthread_cond_init"); exit(1); } if (pthread_cond_init(&(this->condQueueFull), NULL)) { perror("pthread_cond_init"); exit(1); } this->pthreads = (pthread_t *)malloc(sizeof(pthread_t) * this->threadNum); if (NULL == this->pthreads) { perror("pthreads malloc"); exit(1); } this->isPoolClose = false; unsigned int i; for (i = 0; i < this->threadNum; ++i) { pthread_create(&(this->pthreads[i]), NULL, run, (void *)this); } } int ThreadPool::addJob(Job job) { assert(job.doJobFun != NULL); //assert(job.arg != NULL); if (this->isPoolClose) //线程池关闭,线程就退出 { return -1; } pthread_mutex_lock(&(this->mutex)); while ((this->jobQueue.size() == this->maxJobNum)) { //printf("job queue is full\n"); pthread_cond_wait(&(this->condQueueFull), &(this->mutex)); //队列满的时候就等待 } if (this->isPoolClose) //队列关闭或者线程池关闭就退出 { pthread_mutex_unlock(&(this->mutex)); return -1; } if (this->jobQueue.empty()) { this->jobQueue.push_back(job); pthread_cond_broadcast(&(this->condQueueEmpty)); //队列空的时候,有任务来时就通知线程池中的线程:队列非空 } else { this->jobQueue.push_back(job); } //printf("add a job:%d,size:%d\n",(int)job.arg,this->jobQueue.size()); pthread_mutex_unlock(&(this->mutex)); return 0; } int ThreadPool::destroy() { //printf("begin destroy...\n"); pthread_mutex_lock(&(this->mutex)); this->isPoolClose = true; //置队列关闭标志 this->jobQueue.clear(); pthread_mutex_unlock(&(this->mutex)); pthread_cond_broadcast(&(this->condQueueEmpty)); //唤醒线程池中正在阻塞的线程 pthread_cond_broadcast(&(this->condQueueFull)); //唤醒添加任务的threadpool_add_job函数 unsigned int i; for (i = 0; i < this->threadNum; ++i) { pthread_join(this->pthreads[i], NULL); //等待线程池的所有线程执行完毕 //printf("thread %X exit.\n",(unsigned int)this->pthreads[i]); } pthread_mutex_destroy(&(this->mutex)); //清理资源 pthread_cond_destroy(&(this->condQueueEmpty)); pthread_cond_destroy(&(this->condQueueFull)); free(this->pthreads); //printf("end destroy...\n"); return 0; } ThreadPool::~ThreadPool() { //destroy(); }

浙公网安备 33010602011771号