多备份数据更新管理器模板设计(C++ Template)
2013-07-27 12:56
267 查看
在网络服务等需要提供不间断服务的程序中,程序的运行时升级通常都是一项常规任务,例如:
1)运行时修改一些参数配置;
2)运行时修改一个算法模块(动态库);
为了在执行这些任务时,程序不停(仍使用旧配置或旧模块运行),常见的解决方案包括:
1)增加冗余的配置项或模块句柄的存储空间(所有这些数据打包成一个结构体),程序运行时使用其中的一份;当需要更新时,在更新的过程中将新的配置(或模块句柄)内容存储至备用内存;加载完成后将运行时配置(或模块句柄)指针指向新的内存地址。由于修改配置(或模块句柄)的频率远小于这些内容的读取频率,因此一个线程执行更新操作即可。另外,即使外加有多个线程同时读取,由于只涉及到配置项(或模块句柄)的整体结构体的这一个指针修改,读线程读到的值无非是“旧指针”和“新指针”二者之一(如果内存读写模型不支持这一点,或者在这种情况下可能有第三种,甚至第四种情况出现,本方案将不可用),因此程序仍能正常执行,并最终使用更新后的内容运行。
2)程序通过一个主进程协调,具体任务由工作进程完成。外界通知这个主进程使用新的配置(或模块),主进程便创建新的工作进程,这些新启动的进程自然会使用新的配置(或模块);当新创建的进程一切就绪之后,主进程便会通知其他进程结束,并在之后将新的任务委派给新创建的进程。Nginx的设计便是这种方案的一个典型。
这里设计的一个C++模板是上述解决方案1)的一种实现(完整地VS2008项目代码在这里):
测试代码:
1)运行时修改一些参数配置;
2)运行时修改一个算法模块(动态库);
为了在执行这些任务时,程序不停(仍使用旧配置或旧模块运行),常见的解决方案包括:
1)增加冗余的配置项或模块句柄的存储空间(所有这些数据打包成一个结构体),程序运行时使用其中的一份;当需要更新时,在更新的过程中将新的配置(或模块句柄)内容存储至备用内存;加载完成后将运行时配置(或模块句柄)指针指向新的内存地址。由于修改配置(或模块句柄)的频率远小于这些内容的读取频率,因此一个线程执行更新操作即可。另外,即使外加有多个线程同时读取,由于只涉及到配置项(或模块句柄)的整体结构体的这一个指针修改,读线程读到的值无非是“旧指针”和“新指针”二者之一(如果内存读写模型不支持这一点,或者在这种情况下可能有第三种,甚至第四种情况出现,本方案将不可用),因此程序仍能正常执行,并最终使用更新后的内容运行。
2)程序通过一个主进程协调,具体任务由工作进程完成。外界通知这个主进程使用新的配置(或模块),主进程便创建新的工作进程,这些新启动的进程自然会使用新的配置(或模块);当新创建的进程一切就绪之后,主进程便会通知其他进程结束,并在之后将新的任务委派给新创建的进程。Nginx的设计便是这种方案的一个典型。
这里设计的一个C++模板是上述解决方案1)的一种实现(完整地VS2008项目代码在这里):
// // 数据清理函数指针类型 // template<typename T> struct DataCleaner { typedef void (*ClearFun)(T*); }; template<typename T> void _default_reset_fun_(T* t) { memset(t, 0, sizeof(T)); }; // // 多备份数据更新管理器 // template<typename T, const size_t POOLSIZE=2, bool static_memory=true> class LatestDataManager; template<typename T, const size_t POOLSIZE> class LatestDataManager<T, POOLSIZE, true> { public: typedef T value_type; LatestDataManager(){m_clf = _default_reset_fun_<T>;} ~LatestDataManager(){} T& GetCurrent(){ return m_elem[m_current]; } T& GetNext(){ size_t next = (m_current+1)%POOLSIZE; m_clf(&m_elem[next]); return m_elem[next]; } void UseLatest(){ m_current = (m_current+1)%POOLSIZE; } void SetClearFun(typename DataCleaner<T>::ClearFun f){ m_clf = f; } private: T m_elem[POOLSIZE]; size_t m_current; typename DataCleaner<T>::ClearFun m_clf; }; template<typename T, const size_t POOLSIZE> class LatestDataManager<T, POOLSIZE, false> { public: typedef T value_type; LatestDataManager(){memset(m_elem, 0, POOLSIZE*sizeof(T*));} ~LatestDataManager(){} T* GetCurrent(){ return m_elem[m_current]; } T* GetNext(){ size_t next = (m_current+1)%POOLSIZE; if(NULL!=m_elem[next]){ delete m_elem[next]; m_elem[next] = NULL; } m_elem[next] = new T; return m_elem[next]; } void UseLatest(){ m_current = (m_current+1)%POOLSIZE; } void SetClearFun(typename DataCleaner<T>::ClearFun){} private: T* m_elem[POOLSIZE]; size_t m_current; };
测试代码:
template<typename T> void _primdata_reset_fun_(T* t) { *t = 0; } typedef LatestDataManager<int, 2, true> LatestConfig; template<typename T> void _container_reset_fun_(T* t) { if(t) t->clear(); } typedef LatestDataManager<std::vector<std::string>, 2, false> LatestMachines; { LatestConfig g_cfg; g_cfg.SetClearFun( _primdata_reset_fun_< LatestConfig::value_type > ); {// 更新者 ... ... g_cfg.GetNext() = 3; g_cfg.UseLatest(); } {// 使用者 ... ... int config = g_cfg.GetCurrent(); std::cout << config << std::endl; } } { LatestMachines g_lm; g_lm.SetClearFun( _container_reset_fun_< LatestMachines::value_type > ); {// 更新者 ... ... std::vector<std::string>* machines = g_lm.GetNext(); machines->push_back("192.168.0.1"); machines->push_back("192.168.0.2"); machines->push_back("192.168.0.3"); g_lm.UseLatest(); } {// 使用者 ... ... std::vector<std::string>* machines = g_lm.GetCurrent(); for(std::vector<std::string>::iterator it=machines->begin(); it!=machines->end(); ++it) { std::cout << it->c_str() << std::endl; } } }
相关文章推荐
- C++ 程序设计模板Template
- [C++设计模式]template 模板方法模式
- 2017 程序设计实习之C++部分作业题汇总 - F:模板 template
- [C++设计模式]template 模板方法模式
- C++设计模式十--TemplatePattern(模板方法模式)
- c++设计模式----模板方法template method
- 《模式——工程化实现及扩展》(设计模式C# 版)《模板方法模式 Template》——“自我检验"
- 编译器对C++ 11变参模板(Variadic Template)的函数包扩展实现的差异
- 设计模式C++实现(5)——原型模式、模板方法模式
- c++ template(5)模板实战
- 浅谈java 23种设计模式之模板方法模式(Template )
- Java设计模式——模板模式(Template Pattern)
- 设计模式之模板方法模式 c++实现和详细分析
- C++设计模式——模板方法模式
- 设计模式C++学习笔记之九(Template Method模板方法模式)
- C++中 模板Template的使用
- Linux C/C++ 模板:用template消除歧义
- C++设计模式----模板方法模式
- C++设计模式之模板方法模式
- C++ 模板(template)(泛型)入门例子