开始慢慢地把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指针使用时,我将里面的实例代码大致修改如下:
上面的程序运行后,可以发现当share_ptr超过作用域后它管理的指针会被释放,但是reset和print函数并不能给捕获到,
仍然后认为指针是有效的,出现访问了野指针的情况。其实通过内置类型看对象是否被释放,在这个线程里面并不好观察。
我们可以手动构造一个简单的类,通过构造函数和系统函数输出不同信息判断对象是否被释放掉。如实现下面一个简单的类:
将上面代码中的int换成CA类,就可以完全看到对象什么时候析构。论坛上有说使用share_ptr的时候应该搭配使用thread。
否则上面这种情况就需要我们明确地知道发生了什么情况。那这个和手动释放没什么区别了。
下面是一个论坛上看到使用share_ptr在多线程的例子。
代码简洁看着真爽,bind函数也真不错哦。
本来是准备引入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函数也真不错哦。