20110614使用boost使用流水记share_ptr

来源:互联网 发布:xshell mac 破解版 编辑:程序博客网 时间:2024/05/16 05:39
     开始慢慢地把boost库引入到项目中,目前已经使用了filesystem、format、string等字符串操作和文件系统库了。
本来是准备引入share_ptr库的,但是发现想引入的地方就是一个多线程的地方。引入后发现以前写的库接口需要修改。
而且就引入share_ptr库,不引入thread库,share_ptr作为线程参数时还是会有问题。于是暂时对这两个库进行引入。
就仅仅引入了字符串处理和filesystem及datetime库,就是我的exe从原来的编译228k到现在的404k,这个占用有点高,但
对以后开发效率会有所提高就好。
在使用share_ptr的时候,发现了有些情况下需要配合weak_ptr使用,避免指针循环引用。作为一个客户端程序员,一直对
weak_ptr的使用场景是有些迷惑,在网上看到一个朋友说weak_ptr一般在程序架构上使用得比较多,我也记得曾经在看
mysql bench源码时看到过这样的使用,就是因为对boost的不熟,对代码阅读基本是无法继续。
在http://zh.highscore.de/cpp/boost/ 在这里参考weak_ptr指针使用时,我将里面的实例代码大致修改如下:
DWORD WINAPI reset(LPVOID p) {   //Sleep(100);//可以看看和print顺序调整看效果  boost::shared_ptr<int> *sh = static_cast<boost::shared_ptr<int>*>(p);   //sh->reset(); //可以注释和不注释看print函数的输出效果  return 0; } DWORD WINAPI print(LPVOID p) {   //Sleep(20);//可以调整线程顺序看执行效果  boost::weak_ptr<int> *w = static_cast<boost::weak_ptr<int>*>(p);   boost::shared_ptr<int> sh = w->lock();   if (sh)     std::cout << *sh << std::endl;   return 0; } void test_weakptr(){  boost::shared_ptr<int> sh(new int(99));   boost::weak_ptr<int> w(sh);   HANDLE threads[2];   threads[0] = CreateThread(0, 0, reset, &sh, 0, 0);   threads[1] = CreateThread(0, 0, print, &w, 0, 0);   //sh.reset();//验证reset和不调用reset让程序结束析构效果是不一样的,weak_ptr捕获不了对应共享指针是否被析构掉  WaitForMultipleObjects(2, threads, TRUE, INFINITE); //测试sh超过作用域时把这句注释掉}int main() {   test_weakptr();} 


上面的程序运行后,可以发现当share_ptr超过作用域后它管理的指针会被释放,但是reset和print函数并不能给捕获到,
仍然后认为指针是有效的,出现访问了野指针的情况。其实通过内置类型看对象是否被释放,在这个线程里面并不好观察。
我们可以手动构造一个简单的类,通过构造函数和系统函数输出不同信息判断对象是否被释放掉。如实现下面一个简单的类:
class CA{public:CA(){std::cout<<"CA"<<std::endl;m_nA=22;}~CA(){std::cout<<"~CA"<<std::endl;}void printA(){std::cout<<"CA PRINTA  "<<m_nA<<std::endl;}void printAA(){std::cout<<"CA PRINTAA"<<std::endl;}private:int m_nA;};


将上面代码中的int换成CA类,就可以完全看到对象什么时候析构。论坛上有说使用share_ptr的时候应该搭配使用thread。
否则上面这种情况就需要我们明确地知道发生了什么情况。那这个和手动释放没什么区别了。
下面是一个论坛上看到使用share_ptr在多线程的例子。
void thrd_func(shared_ptr<int> sp){}int test(){    shared_ptr<int> sp(new int(10));    boost::thread thrd(boost::bind(thrd_func, sp));    thrd.join();}


代码简洁看着真爽,bind函数也真不错哦。奋斗
原创粉丝点击