赞
踩
一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着 监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利 用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。 线程池的应用场景: 1. 需要大量的线程来完成任务,且完成任务的时间比较短。 WEB服务器完成网页请求这样的任务,使用线程池技 术是非常合适的。因为单个任务小,而任务数量巨大,你可以想象一个热门网站的点击次数。 但对于长时间的任务,比如一个 Telnet连接请求,线程池的优点就不明显了。因为Telnet会话时间比线程的创建时间大多了。 2. 对性能要求苛刻的应用,比如要求服务器迅速响应客户请求。 3. 接受突发性的大量请求,但不至于使服务器因此产生大量线程的应用。突发性大量客户请求,在没有线程池情 况下,将产生大量线程,虽然理论上大部分操作系统线程数目最大值不是问题,短时间内产生大量线程可能使内存到达极限, 出现错误。
- // 线程池类定义
- #pragma once
- #include <vector>
- #include <queue>
- #include <pthread.h>
- #include <iostream>
- #include "thread.hpp"
- #include "mutex.hpp"
- #include "task.hpp"
-
- const int g_thread_num = 3;
-
- // 这样不太合适,因为这样的话,除非把它设计为单例模式,否则所有线程池共用一个任务队列,锁,条件变量,显然是不行的。
- // template <class T>
- // class ThreadPool
- // {
- // public:
- // // 构造函数
- // ThreadPool(int num = g_thread_num)
- // : thread_num_(num)
- // {
- // pthread_mutex_init(&mutex_, nullptr);
- // pthread_cond_init(&cond_, nullptr);
- // }
- // ~ThreadPool()
- // {
- // pthread_mutex_destroy(&mutex_);
- // pthread_cond_destroy(&cond_);
- // }
-
- // public:
- // void run()
- // {
- // pthread_t tid;
- // // 让所有线程执行起来,等待任务,执行任务
- // for (int i = 0; i < thread_num_; ++i)
- // {
- // pthread_create(&tid, nullptr, routine, (void *)this);
- // }
- // }
- // // 因为类成员函数,有一个隐藏的this指针,不能直接作为void* (*p)(void*)函数
- // //因此设置为static成员函数,但是routine内部要访问锁和条件变量,以及任务队列,因此把它们设置为static数据成员。
- // //但是,这样的话,所有线程池都使用一个锁,一个条件变量,一个任务队列,这无疑不是最佳方案。
- // static void *routine(void *args) // 消费者pop任务,此处为线程。
- // {
- // ThreadPool *tp = (ThreadPool *)args;
- // while (true)
- // {
- // pthread_mutex_lock(&mutex_);
- // while (task_queue_.empty())
- // pthread_cond_wait(&cond_, &mutex_); // 线程等待任务投放,并解锁
- // T t;
- // t = task_queue_.front();
- // task_queue_.pop();
- // std::cout << "线程 " <&

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。