一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够 保证内核的充分利用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。
#ifndef __M_TP_H__
#define __M_TP_H__
#include <iostream>
#include <queue>
#include <pthread.h>
#define MAX_THREAD 5
typedef bool (*handler_t)(int);
class ThreadTask
{
private:
int _data;
handler_t _handler;
public:
ThreadTask():_data(-1), _handler(NULL) {}
ThreadTask(int data, handler_t handler) {
_data= data;
_handler = handler;
}
void SetTask(int data, handler_t handler) {
_data = data;
_handler = handler;
}
void Run() {
_handler(_data);
}
};
class ThreadPool
{
private:
int _thread_max;
int _thread_cur;
bool _tp_quit;
std::queue<ThreadTask *> _task_queue;
pthread_mutex_t _lock;
pthread_cond_t _cond;
private:
void LockQueue() {
pthread_mutex_lock(&_lock);
}
void UnLockQueue() {
pthread_mutex_unlock(&_lock);
}
void WakeUpOne() {
pthread_cond_signal(&_cond);
}
void WakeUpAll() {
pthread_cond_broadcast(&_cond);
}
void ThreadQuit() {
_thread_cur--;
UnLockQueue();
pthread_exit(NULL);
}
void ThreadWait(){
if (_tp_quit) {
ThreadQuit();
}
pthread_cond_wait(&_cond, &_lock);
}
bool IsEmpty() {
return _task_queue.empty();
}
static void *thr_start(void *arg) {
ThreadPool *tp = (ThreadPool*)arg;
while(1) {
tp->LockQueue();
while(tp->IsEmpty()) {
tp->ThreadWait();
}
ThreadTask *tt;
tp->PopTask(&tt);
tp->UnLockQueue();
tt->Run();
delete tt;
}
return NULL;
}
public:
ThreadPool(int max=MAX_THREAD):_thread_max(max), _thread_cur(max),
_tp_quit(false) {
pthread_mutex_init(&_lock, NULL);
pthread_cond_init(&_cond, NULL);
}
~ThreadPool() {
pthread_mutex_destroy(&_lock);
pthread_cond_destroy(&_cond);
}
bool PoolInit() {
pthread_t tid;
for (int i = 0; i < _thread_max; i++) {
int ret = pthread_create(&tid, NULL, thr_start, this);
if (ret != 0) {
std::cout<<"create pool thread error\n";
return false;
}
}
return true;
}
bool PushTask(ThreadTask *tt) {
LockQueue();
if (_tp_quit) {
UnLockQueue();
return false;
}
_task_queue.push(tt);
WakeUpOne();
UnLockQueue();
return true;
}
bool PopTask(ThreadTask **tt) {
*tt = _task_queue.front();
_task_queue.pop();
return true;
}
bool PoolQuit() {
LockQueue();
_tp_quit = true;
UnLockQueue();
while(_thread_cur > 0) {
WakeUpAll();
usleep(1000);
}
return true;
}
};
#endif
bool handler(int data)
{
srand(time(NULL));
int n = rand() % 5;
printf("Thread: %p Run Tast: %d--sleep %d sec\n", pthread_self(), data, n);
sleep(n);
return true;
}
int main()
{
int i;
ThreadPool pool;
pool.PoolInit();
for (i = 0; i < 10; i++) {
ThreadTask *tt = new ThreadTask(i, handler);
pool.PushTask(tt);
}
pool.PoolQuit();
return 0;
}
运行结果:
单例模式是一种 “经典的, 常用的, 常考的” 设计模式.
懒汉方式最核心的思想是 “延时加载”. 从而能够优化服务器的启动速度.
template <typename T>
class Singleton {
static T data;
public:
static T* GetInstance() {
return &data;
}
};
template <typename T>
class Singleton {
static T* inst;
public:
static T* GetInstance() {
if (inst == NULL) {
inst = new T();
}
return inst;
}
};
// 懒汉模式, 线程安全
template <typename T>
class Singleton {
volatile static T* inst; // 需要设置 volatile 关键字, 否则可能被编译器优化.
static std::mutex lock;
public:
static T* GetInstance() {
if (inst == NULL) { // 双重判定空指针, 降低锁冲突的概率, 提高性能.
lock.lock(); // 使用互斥锁, 保证多线程情况下也只调用一次 new.
if (inst == NULL) {
inst = new T();
}
lock.unlock();
}
return inst;
}
};
注意事项: