简易线程池的实现
1 线程池
为了避免多线程操作过程种线程频繁申请和释放所带来的性能消耗,可以提前创建多个线程,当有任务到来时从线程池中选择一个线程执行,执行完后继续在线程池中待命。
核心是使用一个工作队列,主线程往工作队列中添加工作,工作线程从队列中取出工作并执行。
对工作队列的操作就是经典的生产者—消费者模型,需要用到互斥锁和条件变量。
2 工作定义
通过函数指针指向执行函数。
1 2 3 4 | typedef struct Task{ void (*func)( void * arg); void * arg; }Task; |
3 线程池定义
使用 list 容器来存储工作,定义工作队列的最大数 m_max_requests 和 线程总数 m_max_threads。在对工作队列操作时需要用到互斥锁 m_mutex_pool,条件变量 m_notfull 和 m_notempty。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | class ThreadPool{ public : ThreadPool( int m_max_threads, int m_max_requests); ~ThreadPool(); bool addWork( void (*func)( void *), void * arg); private : static void * worker( void * arg); void run(); private : std::list<Task*> m_workqueue; /*工作队列*/ int m_max_requests; /*请求队列中允许的最大请求数*/ int m_max_threads; /*线程总数*/ pthread_t* m_worker_threads; /*工作线程*/ pthread_mutex_t m_mutex_pool; pthread_cond_t m_notfull; pthread_cond_t m_notempty; bool m_stop; }; ThreadPool::ThreadPool( int m_max_threads, int m_max_requests): m_max_threads(m_max_threads), m_max_requests(m_max_requests), m_stop( false ){ if (m_max_threads <= 0 || m_max_requests <= 0){ throw std::exception(); } /*创建线程池*/ m_worker_threads = new pthread_t[m_max_threads]; if (!m_worker_threads){ throw std::exception(); } //memset(m_worker_threads, 0, sizeof(m_worker_threads)); /*初始化互斥锁、条件变量*/ if (0 != pthread_mutex_init(&m_mutex_pool, NULL) || 0 != pthread_cond_init(&m_notfull, NULL) || 0 != pthread_cond_init(&m_notempty, NULL)){ throw std::exception(); } /*创建工作线程*/ for ( int i=0; i<m_max_threads; ++i){ printf ( "Create the %dth thread\n" , i); if (0 != pthread_create(&m_worker_threads[i], 0, worker, this )){ delete []m_worker_threads; throw std::exception(); }; if (pthread_detach(m_worker_threads[i])){ delete [] m_worker_threads; throw std::exception(); } } } ThreadPool::~ThreadPool(){ delete []m_worker_threads; m_stop = true ; } bool ThreadPool::addWork( void (*func)( void *), void * arg){ pthread_mutex_lock(&m_mutex_pool); while (!m_stop && m_workqueue.size() >= m_max_requests){ pthread_cond_wait(&m_notfull, &m_mutex_pool); } if (m_stop){ pthread_mutex_unlock(&m_mutex_pool); return false ; } /*添加工作*/ Task* task = new Task; task->func = func; task->arg = arg; m_workqueue.push_back(task); pthread_mutex_unlock(&m_mutex_pool); pthread_cond_signal(&m_notempty); return true ; } void * ThreadPool::worker( void * arg){ ThreadPool* pool = (ThreadPool*)arg; pool->run(); return pool; } void ThreadPool::run(){ while (1){ pthread_mutex_lock(&m_mutex_pool); while (m_workqueue.empty() && !m_stop){ pthread_cond_wait(&m_notempty, &m_mutex_pool); } /*从工作队列中取任务*/ Task* task = m_workqueue.front(); m_workqueue.pop_front(); pthread_mutex_unlock(&m_mutex_pool); pthread_cond_signal(&m_notfull); printf ( "Thread %ld start working...\n" , pthread_self()); /*执行任务*/ task->func(task->arg); delete task; printf ( "Thread %ld end working...\n" , pthread_self()); } } #endif |
4 测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include "threadpool.h" #include<iostream> #include<unistd.h> using namespace std; void taskFunc( void * arg) { int num = *( int *)arg; printf ( "Thread %ld is working, number = %d\n" , pthread_self(), num); sleep(1); } int main(){ ThreadPool* pool = new ThreadPool(10, 20); for ( int i = 0; i < 100; ++i) { int * num = ( int *) malloc ( sizeof ( int )); *num = i; pool->addWork(taskFunc, num); } sleep(30); return 0; } |
References:
- 手写线程池 - C 语言版
- 《Linux高性能服务器编程》
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2019-04-20 Redhat更换yum源