您的位置:首页 > 房产 > 家装 > 台湾云服务器去哪里买_小程序开发接单_百度大搜推广开户_网络营销与直播电商专业就业前景

台湾云服务器去哪里买_小程序开发接单_百度大搜推广开户_网络营销与直播电商专业就业前景

2024/10/5 22:26:22 来源:https://blog.csdn.net/qq_37281656/article/details/142299478  浏览:    关键词:台湾云服务器去哪里买_小程序开发接单_百度大搜推广开户_网络营销与直播电商专业就业前景
台湾云服务器去哪里买_小程序开发接单_百度大搜推广开户_网络营销与直播电商专业就业前景
  • 单例模式的线程安全

    • 需要双重判空指针,降低锁冲突的概率,提高性能
    • 原因1:
      • 当第一次实例化单例时,可能有多个线程同时到来,并且svr指针为空
      • 这时他们就会去竞争锁,但只有一个线程会最快拿到锁,并且成功实例化出单例对象
      • 但此时如果不加双重判空指针,那些也进了第一层if判断的,仍然会去实例化出对象
    • 原因2:
      • 为了线程安全,必然要加锁,加锁之后再去判空
      • 但每次调用GetInstance()都需要去获得锁,释放锁,效率低下
      • 此时再加一层外层if判空,这样就会避免后续调用GetInstance()时没必要的锁竞争
  • static void *ThreadRoutine(void *args)为什么要设置为static方法?

    • pthread_create传递给线程的方法只能是返回值为void*,参数为void*的函数
    • static将函数方法声明为静态方法,此时该方法没有隐含的this指针,就可以在类内把这个方法传递给线程调用了
      int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);
      
  • while()防止伪唤醒

    • 可能条件变量唤醒线程时,有多个线程同时被唤醒,但是只有一个最快的线程PopTask()可以拿到任务,此时其他线程就会出错
    • while()可以在被唤醒的情况下,再次判断任务队列是否有任务
    • 这样可以保证,在某个线程醒来的时候,一定是占有互斥锁的
static const int THREAD_POOL_NUM = 10;// 单例模式
class ThreadPool
{
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 = new ThreadPool(num);_tp->Init();}pthread_mutex_unlock(&sMtx);}return _tp;}// static使该成员函数没有this指针,因为线程执行的函数只能有一个void*参数static void *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();}}bool Init(){for (int i = 0; i < _num; i++){pthread_t tid;if (pthread_create(&tid, nullptr, ThreadRoutine, this) != 0){LOG(FATAL, "Create ThreadPool Error");return false;}}LOG(INFO, "Create ThreadPool Success");return true;}void Push(const Task& task) // in{Lock();_taskQueue.push(task); // 任务队列为临界资源,操作要加锁Unlock();ThreadWakeUp();}void Pop(Task& task) // out{task = _taskQueue.front();_taskQueue.pop();}void ThreadWait(){pthread_cond_wait(&_cond, &_mtx);}void ThreadWakeUp(){pthread_cond_signal(&_cond);}bool TaskQueueIsEmpty(){return !_taskQueue.size();}void Lock(){pthread_mutex_lock(&_mtx);}void Unlock(){pthread_mutex_unlock(&_mtx);}bool IsStop(){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;

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com