当前位置: 首页 > news >正文

网站建设管理经验做法盗网站asp源码

网站建设管理经验做法,盗网站asp源码,桂平网站建设,专业网站建设全包#x1f308;个人主页#xff1a; 南桥几晴秋 #x1f308;C专栏#xff1a; 南桥谈C #x1f308;C语言专栏#xff1a; C语言学习系列 #x1f308;Linux学习专栏#xff1a; 南桥谈Linux #x1f308;数据结构学习专栏#xff1a; 数据结构杂谈 #x1f308;数据… 个人主页 南桥几晴秋 C专栏 南桥谈C C语言专栏 C语言学习系列 Linux学习专栏 南桥谈Linux 数据结构学习专栏 数据结构杂谈 数据库学习专栏 南桥谈MySQL Qt学习专栏 南桥谈Qt 菜鸡代码练习 练习随想记录 git学习 南桥谈Git 本科在读菜鸡一枚指出问题及时改正 文章目录 单例模式概述饿汉实现方式和懒汉实现方式懒汉方式实现在单线程场景中多线程场景中 可重入vs线程安全常见锁概念死锁死锁四个必要条件避免死锁避免死锁算法 STL、智能指针与线程安全STL中的容器是否是线程安全的智能指针是否是线程安全的 其他常见的各种锁 单例模式概述 某些类, 只应该具有一个对象(实例), 就称之为单例。 例如一个男人只能有一个媳妇。 在很多服务器开发场景中, 经常需要让服务器加载很多的数据 (上百G) 到内存中。此时往往要用一个单例的类来管理这些数据。 饿汉实现方式和懒汉实现方式 如何理解饿汉方式和懒汉方式 饿汉方式吃完饭直接洗完下一次吃饭的时候就可以直接使用 懒汉方式吃完饭先放着等下一顿吃饭的时候再去洗碗。 懒汉方式最核心的思想是 “延时加载”从而能够优化服务器的启动速度。 懒汉方式实现 在单线程场景中 //ThreadPool.hpp #pragma once#includeiostream #includeunistd.h #includestring #includevector #includequeue #includefunctional #includeThread.hpp #includeLog.hppusing namespace threadModel; using namespace log_ns;static const int gdefaultnum5;void test() {while(true){std::couthello worldstd::endl;sleep(1);} }templatetypename T class ThreadPool { private:void LockQueue(){pthread_mutex_lock(_mutex);}void UnlockQueue(){pthread_mutex_unlock(_mutex);}void Wakeup(){pthread_cond_signal(_cond);}void WakeupAll(){pthread_cond_broadcast(_cond);}void Sleep(){pthread_cond_wait(_cond,_mutex);}bool IsEmpty(){return _task_queue.empty();}void HandlerTask(const std::string name) // this{while (true){LockQueue();//如果队列为空(有任务)while(IsEmpty()_isrunning) //线程没有任务但是在工作继续休眠{_sleep_thread_num;LOG(INFO,%s thread sleep begin!\n,name.c_str());Sleep();LOG(INFO,%s thread wakeup!\n,name.c_str());_sleep_thread_num--;}if(IsEmpty()!_isrunning) // 任务是空的并且线程退出工作{UnlockQueue();LOG(INFO,%s quit\n,name.c_str());break;}// 队列不为空有任务 或者 队列被唤醒// 取任务T t_task_queue.front();_task_queue.pop();UnlockQueue();// 此处任务已经不在任务队列中任务已经被拿走处理任务和临界资源是两码事t(); // 处理任务不能不用也不能在临界区中处理LOG(DEBUG,hander task done, task is: \n%s,t.result().c_str());}}void Init(){func_t func std::bind(ThreadPool::HandlerTask, this, std::placeholders::_1);for (int i 0; i _thread_num; i){std::string threadname thread- std::to_string(i 1);_threads.emplace_back(threadname, func);LOG(DEBUG, construct thread %s done, init success.\n, threadname.c_str());}}void Start(){_isrunning true;for (auto thread : _threads){LOG(DEBUG, Start thread %s done.\n, thread.Name().c_str());thread.Start();}}ThreadPool(int thread_num gdefaultnum): _thread_num(thread_num), _isrunning(false) // 刚开始线程没有使用,_sleep_thread_num(0){pthread_mutex_init(_mutex, nullptr);pthread_cond_init(_cond, nullptr);}ThreadPool(const ThreadPoolT )delete;void operator(const ThreadPoolT )delete;public:void Stop(){LockQueue();_isrunningfalse;WakeupAll();UnlockQueue();LOG(INFO,Thread Pool Stop Success!\n);}static ThreadPoolT *GetInstance(){if(_tpnullptr){LOG(INFO,create threadpool\n);_tpnew ThreadPool();_tp-Init();_tp-Start();}else{LOG(INFO,get threadpool\n);} return _tp;}void Equeue(const T in){LockQueue();if(_isrunning){_task_queue.push(in);// 如果当前有线程在等待需要唤醒if(_sleep_thread_num0){Wakeup();}}UnlockQueue();}~ThreadPool(){pthread_mutex_destroy(_mutex);pthread_cond_destroy(_cond);} private:int _thread_num;std::vectorThread _threads; // 管理多个线程std::queueT _task_queue; // 任务队列bool _isrunning; //当前线程是否在工作int _sleep_thread_num; //计数器休眠的线程个数pthread_mutex_t _mutex;pthread_cond_t _cond;//单例程模式static ThreadPoolT* _tp;};//静态指针初始化必须在类外初始化 templatetypename T ThreadPoolT *ThreadPoolT:: _tpnullptr; 定义了一个静态成员函数 GetInstance()用于实现线程池的单例模式 单例模式: 这个函数的目的是确保 ThreadPool 类只有一个实例存在。它利用静态指针 _tp 来检查是否已经创建了一个实例。实例化逻辑: 空指针检查: if (_tp nullptr)检查静态指针 _tp 是否为空。如果为空表示尚未创建线程池实例。 创建实例: 在指针为空的情况下会记录日志LOG(INFO, create threadpool\n);然后使用new关键字创建一个新的 ThreadPool 实例。接着调用 Init() 方法进行初始化可能用于设置线程池的初始状态。然后调用 Start() 方法启动线程池以便开始处理任务。 获取现有实例: 如果 _tp 不为空说明线程池实例已存在则记录另一条日志LOG(INFO, get threadpool\n);以指示已经获取到现有实例。 通过检查静态指针 _tp 的状态来实现线程池的单例模式。它在第一次调用时创建并初始化线程池实例随后的调用将返回相同的实例从而避免不必要的资源浪费和多重实例的问题。这就是按需加载。 多线程场景中 //ThreadPool.hpp #pragma once#includeiostream #includeunistd.h #includestring #includevector #includequeue #includefunctional #includeThread.hpp #includeLog.hpp #includeLockGuard.hppusing namespace threadModel; using namespace log_ns;static const int gdefaultnum5;void test() {while(true){std::couthello worldstd::endl;sleep(1);} }templatetypename T class ThreadPool { private:void LockQueue(){pthread_mutex_lock(_mutex);}void UnlockQueue(){pthread_mutex_unlock(_mutex);}void Wakeup(){pthread_cond_signal(_cond);}void WakeupAll(){pthread_cond_broadcast(_cond);}void Sleep(){pthread_cond_wait(_cond,_mutex);}bool IsEmpty(){return _task_queue.empty();}void HandlerTask(const std::string name) // this{while (true){LockQueue();//如果队列为空(有任务)while(IsEmpty()_isrunning) //线程没有任务但是在工作继续休眠{_sleep_thread_num;LOG(INFO,%s thread sleep begin!\n,name.c_str());Sleep();LOG(INFO,%s thread wakeup!\n,name.c_str());_sleep_thread_num--;}if(IsEmpty()!_isrunning) // 任务是空的并且线程退出工作{UnlockQueue();LOG(INFO,%s quit\n,name.c_str());break;}// 队列不为空有任务 或者 队列被唤醒// 取任务T t_task_queue.front();_task_queue.pop();UnlockQueue();// 此处任务已经不在任务队列中任务已经被拿走处理任务和临界资源是两码事t(); // 处理任务不能不用也不能在临界区中处理LOG(DEBUG,hander task done, task is: \n%s,t.result().c_str());}}void Init(){func_t func std::bind(ThreadPool::HandlerTask, this, std::placeholders::_1);for (int i 0; i _thread_num; i){std::string threadname thread- std::to_string(i 1);_threads.emplace_back(threadname, func);LOG(DEBUG, construct thread %s done, init success.\n, threadname.c_str());}}void Start(){_isrunning true;for (auto thread : _threads){LOG(DEBUG, Start thread %s done.\n, thread.Name().c_str());thread.Start();}}ThreadPool(int thread_num gdefaultnum): _thread_num(thread_num), _isrunning(false) // 刚开始线程没有使用,_sleep_thread_num(0){pthread_mutex_init(_mutex, nullptr);pthread_cond_init(_cond, nullptr);}ThreadPool(const ThreadPoolT )delete;void operator(const ThreadPoolT )delete;public:void Stop(){LockQueue();_isrunningfalse;WakeupAll();UnlockQueue();LOG(INFO,Thread Pool Stop Success!\n);}static ThreadPoolT *GetInstance(){if(_tpnullptr){LockGuard lockguard(_sig_mutex); //解决多线程场景if(_tpnullptr){LOG(INFO,create threadpool\n);_tpnew ThreadPool();_tp-Init();_tp-Start();}else{LOG(INFO,get threadpool\n);} }return _tp;}void Equeue(const T in){LockQueue();if(_isrunning){_task_queue.push(in);// 如果当前有线程在等待需要唤醒if(_sleep_thread_num0){Wakeup();}}UnlockQueue();}~ThreadPool(){pthread_mutex_destroy(_mutex);pthread_cond_destroy(_cond);} private:int _thread_num;std::vectorThread _threads; // 管理多个线程std::queueT _task_queue; // 任务队列bool _isrunning; //当前线程是否在工作int _sleep_thread_num; //计数器休眠的线程个数pthread_mutex_t _mutex;pthread_cond_t _cond;//单例程模式static ThreadPoolT* _tp;static pthread_mutex_t _sig_mutex;};//静态指针初始化必须在类外初始化 templatetypename T ThreadPoolT *ThreadPoolT:: _tpnullptr;templatetypename T pthread_mutex_t ThreadPoolT::_sig_mutexPTHREAD_MUTEX_INITIALIZER;多线程场景中在GetInstance()内部需要创建一个 LockGuard 对象以自动加锁 _sig_mutex 互斥锁。这确保在进入临界区时只有一个线程可以访问此代码块以避免多个线程同时创建实例。 可重入vs线程安全 线程安全多个线程并发同一段代码时不会出现不同的结果。常见对全局变量或者静态变量进行操作并且没有锁保护的情况下会出现该问题。 重入同一个函数被不同的执行流调用当前一个流程还没有执行完就有其他的执行流再次进入我们称之为重入。一个函数在重入的情况下运行结果不会出现任何不同或者任何问题则该函数被称为可重入函数否则是不可重入函数。 如果一个函数可重入那么在多线程调用时一定是安全的如果一个函数不可重入那么这个函数可能不是线程安全的。 常见锁概念 死锁 死锁是指在一组进程中的各个进程均占有不会释放的资源但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态。 一个线程一把锁也可能出现死锁当在给一个线程加锁的后没有解锁而是继续加锁。 死锁四个必要条件 互斥条件一个资源每次只能被一个执行流使用请求与保持条件一个执行流因请求资源而阻塞时对已获得的资源保持不放不剥夺条件:一个执行流已获得的资源在末使用完之前不能强行剥夺循环等待条件:若干执行流之间形成一种头尾相接的循环等待资源的关系 避免死锁 破坏死锁的四个必要条件加锁顺序一致避免锁未释放的场景资源一次性分配 避免死锁算法 死锁检测算法(了解)银行家算法了解 STL、智能指针与线程安全 STL中的容器是否是线程安全的 不是. 原因是, STL 的设计初衷是将性能挖掘到极致, 而一旦涉及到加锁保证线程安全, 会对性能造成巨大的影响. 而且对于不同的容器, 加锁方式的不同, 性能可能也不同(例如hash表的锁表和锁桶). 因此 STL 默认不是线程安全. 如果需要在多线程环境下使用, 往往需要调用者自行保证线程安全 智能指针是否是线程安全的 对于 unique_ptr, 由于只是在当前代码块范围内生效, 因此不涉及线程安全问题. 对于 shared_ptr, 多个对象需要共用一个引用计数变量, 所以会存在线程安全问题. 但是标准库实现的时候考虑到了这个问题, 基于原子操作(CAS)的方式保证 shared_ptr 能够高效, 原子的操作引用计数. 其他常见的各种锁 悲观锁在每次取数据时总是担心数据会被其他线程修改所以会在取数据前先加锁读锁写锁行锁等当其他线程想要访问数据时被阻塞挂起。乐观锁每次取数据时候总是乐观的认为数据不会被其他线程修改因此不上锁。但是在更新数据前会判断其他数据在更新前有没有对数据进行修改。主要采用两种方式版本号机制和CAS操作。CAS操作当需要更新数据时判断当前内存值和之前取得的值是否相等。如果相等则用新值更新。若不等则失败失败则重试一般是一个自旋的过程即不断重试。
http://www.tj-hxxt.cn/news/223525.html

相关文章:

  • 电器网站建设免费咨询上海网站架设
  • 做外销网站总部在深圳的互联网公司
  • 怎么做网站添加二维码男科医院咨询免费
  • 网站的评测系统怎么做的做招聘的h5用哪个网站
  • 网站流量盈利知己图书网站建设策划书
  • 视频网页制作教程360优化大师官网
  • 如何给网站的关键词做排名架设一个网站
  • 网站不备案不能访问吗wordpress如何添加百度地图
  • 手机静态网站开发制作中国门户网站建设重要性
  • 订阅号可以做网站么二手房装修
  • 自己做网站能赚钱么网站论坛模板下载
  • 兰州网站分类导航企业网站推广方案设计
  • 怎么弄免费的php空间做网站中国哪家做网站的公司最大
  • 淘宝网站建设目标是什么意思江油网站制作
  • 手机h5免费模板网站模板中国建筑未来走势预测
  • 网站优化软件有哪些php网站开发技术 pdf
  • 淄川网站建设yx718wordpress xampp
  • 视频工厂网站建设物流公司怎么做网站
  • 网站备案在线注销html成品网页模板下载
  • 表白网站在线制作软件软件开发文档
  • 兰州网站程序建设浙江建设网一官方网站
  • iapp网站做软件美篇制作app下载安装免费
  • 在手机上如何制作网站建筑工程信息网站
  • 专门做评测的网站flash中国官网
  • python做的网站有哪些家谱用网站做
  • 企业做网站有用吗工业和信息化部icp网站备案系统
  • dede 网站图标微信公众号如何开通小程序
  • 电子商务网站开发的过程wordpress 创意
  • 培训网站系统建设浙江工业设计公司
  • 如何做x响应式网站免费制作招聘的app