- 单例模式的线程安全- 需要双重判空指针,降低锁冲突的概率,提高性能- 原因1:- 当第一次实例化单例时,可能有多个线程同时到来,并且svr指针为空- 这时他们就会去竞争锁,但只有一个线程会最快拿到锁,并且成功实例化出单例对象- 但此时如果不加双重判空指针,那些也进了第一层if判断的,仍然会去实例化出对象- 原因2:- 为了线程安全,必然要加锁,加锁之后再去判空- 但每次调用
GetInstance()
都需要去获得锁,释放锁,效率低下- 此时再加一层外层if判空,这样就会避免后续调用GetInstance()
时没必要的锁竞争 static void *ThreadRoutine(void *args)
为什么要设置为static方法?-pthread_create
传递给线程的方法只能是返回值为void*
,参数为void*
的函数- static将函数方法声明为静态方法,此时该方法没有隐含的this指针,就可以在类内把这个方法传递给线程调用了intpthread_create(pthread_t *thread,const pthread_attr_t *attr,void*(*start_routine)(void*),void*arg);
- while()防止伪唤醒- 可能条件变量唤醒线程时,有多个线程同时被唤醒,但是只有一个最快的线程
PopTask()
可以拿到任务,此时其他线程就会出错- while()可以在被唤醒的情况下,再次判断任务队列是否有任务- 这样可以保证,在某个线程醒来的时候,一定是占有互斥锁的
staticconstint THREAD_POOL_NUM =10;// 单例模式classThreadPool{public:static ThreadPool *GetInstance(int num = THREAD_POOL_NUM){static pthread_mutex_t sMtx = PTHREAD_MUTEX_INITIALIZER;if(_tp ==nullptr){pthread_mutex_lock(&sMtx);if(_tp ==nullptr)// 双重判断,以防线程安全问题{
_tp =newThreadPool(num);
_tp->Init();}pthread_mutex_unlock(&sMtx);}return _tp;}// static使该成员函数没有this指针,因为线程执行的函数只能有一个void*参数staticvoid*ThreadRoutine(void*args){
ThreadPool *tp =(ThreadPool *)args;while(true){
Task task;
tp->Lock();while(tp->TaskQueueIsEmpty())// while防止伪唤醒{
tp->ThreadWait();}
tp->Pop(task);
tp->Unlock();// 注意,不要在临界资源区内处理任务哦~
task.ProcessOn();}}boolInit(){for(int i =0; i < _num; i++){
pthread_t tid;if(pthread_create(&tid,nullptr, ThreadRoutine,this)!=0){LOG(FATAL,"Create ThreadPool Error");returnfalse;}}LOG(INFO,"Create ThreadPool Success");returntrue;}voidPush(const Task& task)// in{Lock();
_taskQueue.push(task);// 任务队列为临界资源,操作要加锁Unlock();ThreadWakeUp();}voidPop(Task& task)// out{
task = _taskQueue.front();
_taskQueue.pop();}voidThreadWait(){pthread_cond_wait(&_cond,&_mtx);}voidThreadWakeUp(){pthread_cond_signal(&_cond);}boolTaskQueueIsEmpty(){return!_taskQueue.size();}voidLock(){pthread_mutex_lock(&_mtx);}voidUnlock(){pthread_mutex_unlock(&_mtx);}boolIsStop(){return _stop;}~ThreadPool(){pthread_mutex_destroy(&_mtx);pthread_cond_destroy(&_cond);}private:ThreadPool(int num = THREAD_POOL_NUM):_num(num),_stop(false){pthread_mutex_init(&_mtx,nullptr);pthread_cond_init(&_cond,nullptr);}ThreadPool(const ThreadPool &)=delete;private:int _num;bool _stop;
std::queue<Task> _taskQueue;
pthread_mutex_t _mtx;
pthread_cond_t _cond;static ThreadPool *_tp;};
ThreadPool* ThreadPool::_tp =nullptr;
本文转载自: https://blog.csdn.net/qq_37281656/article/details/142299478
版权归原作者 DieSnowK 所有, 如有侵权,请联系我们删除。
版权归原作者 DieSnowK 所有, 如有侵权,请联系我们删除。