标签:
多线程下的内存管理与单线程下是完全不同的,因为heap是一个可以被全局改动的资源,所以所有的线程都有可能去访问这一资源,这回导致很多的race_conditions。
1 namespace std{ 2 typedef void(*new_handler)();//没有参数以及返回值 3 new_handler set_new_handler(new_handler p) throw(); 4 }
1 class NewHandlerHolder{ 2 public: 3 explicit NewHandlerHolder(std::new_handler nh) 4 :handler(nh){} 5 ~NewHandlerHolder() 6 std::set_new_handler(handler); //将状态恢复到之前的状态 7 private: 8 new_handler handler; 9 NewHandlerHolder(const NewHandlerHolder &); //禁止这两种操作 10 NewHandlerHolder & operator(const NewHandlerHolder &); 11 };
上面这个就可以被自定义的一个类所使用了:
1 void * Widget::operator new(std::size_t size) throw (std::bad_alloc) 2 { 3 NewHandlerHolder h(std::set_new_handler(currentHandler));//使用上面的RAII将handler资源正确的管理。 4 return ::operator new(size);//使用自定义的new 5 }
实际上,可以将上面的NewHandlerHolder设计成为一个基类模板,这样derived_class科技继承他们需要的set_new_handler以及operator_new,template用于保证每一个derived_class获得一个实体互异的currentHandler成员变量。下为这个模板:
1 template<typename T> //这里的typename T 并未被使用,作用下面会说 2 class NewHandlerSupport{ 3 public: 4 static std::new_handler set_new_handler(std::new_handler p) throw(); 5 static void * operator new(std::size_t size) throw(std::bad_alloc); 6 ... 7 private: 8 static std::new_handler currentHandler; 9 }; 10 template<typename T> 11 static std::new_handler 12 NewHandlerSupport<T> set_new_handler(std::new_handler p) throw() 13 { 14 std::new_handler oldHandler = currentHandler; 15 currentHandler = p; 16 return oldHandler; 17 } 18 template<typename T> 19 static void * 20 NewHandlerSupport<T>::operator new(std::size_t size) throw(std::bad_alloc) 21 { 22 NewHandlerHolder h(std::set_new_handler(currentHandler)); 23 return ::operator(size);//调用全局的operatornew,防止递归的调用自己。 24 }
有了这个模板,那么为Widget提供专属的set_new_handler以及operator都是很容易的了。继承上面的模板并特例化就可以了:
1 class Widget : public NewHandlerSupport<Widget>{ 2 ... 3 };
标签:
原文地址:http://www.cnblogs.com/-wang-cheng/p/4889840.html