boost::shar

编程入门 行业动态 更新时间:2024-10-26 01:30:39

<a href=https://www.elefans.com/category/jswz/34/1768537.html style=boost::shar"/>

boost::shar

boost学习笔记一: 使用boost::shared_ptr做为线程的参数
 
 
使用linux下的线程创建函数pthread_create已久,在传递给它void*型的入口参数时,总是两种方式:
1. 在堆中创建,传入参数指针至线程中,由线程内部释放或等待线程退出后再释放;
2. 不在堆中创建或使用全局变量;

虽然在各种书上提及这种方式的种种不足,但我一直用得还挺好.主要就是注意资源的释放就成,毕竟这种低层的API能给程序员最大的灵活性,所谓有空间才能发挥嘛.但不可否认的是,站得更高是会看得更远.一些设计确实能让代码变得更加简洁,并且不用关注太多低层的细节.其实我一直觉得细节很重要,但要会取舍.


看看以下几个类如何能让代码更优雅:
boost::shared_ptr
boost::bind
boost::thread


作为比较,以下是linux下标准的创建线程的例子:



/*
  build args:
  -lpthread
*/

#include <pthread.h>
#include <iostream>
#include <string>

using namespace std;

class B
{
public:
    B() {cout << "construct B;" << endl;}
    void out() { cout << "B::out();" << endl; }
    ~B(){ cout << "destroy B;" << endl;}
};

void* fun2(void* p)
{
    B* pb =(B*)p;
    pb->out();
    sleep(3);
    delete pb; // 在这里释放主线程中创建的对象.
}

void fun()
{
    pthread_attr_t ta;
    pthread_attr_init(&ta);
    pthread_t tid;

    B *pb = new B(); // 创建B的对象作为线程的参数
    pthread_create(&tid, &ta, (void*(*)(void*))fun2, (void*)pb);
    pthread_join(tid, NULL);
}

int main()
{
    fun();
    cout << "FINISH" << endl;
}



如果用上shared_ptr,就不再需要在线程中来删除资源了.因为当引用计数为0时,shared_ptr会自动的销毁掉内含的指针.



/*
  build args(boost 1.34.1 installed /usr/local/):
  -I/usr/local/include/boost-1_34_1 -L/usr/local/lib -lboost_thread-gcc41-mt
*/


#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>

#include <iostream>
#include <string>

using namespace std;

class B
{
public:
    B() {cout << "construct B;" << endl;}
    void out() { cout << "B::out();" << endl; }
    ~B(){ cout << "destroy B;" << endl;}
};

void* fun2(void* p)
{
    /*
       转呀转就把原类型转回来了.
    */
    boost::shared_ptr<B> pb = *(boost::shared_ptr<B>*)(p);
    pb->out();

    sleep(10);
    
    // 注意在这里就不再需要delete
}



void fun()
{
    /*
       boost中的引用指针计数器(shared_ptr),这个shared_ptr对象内含B的对象指针,
       但由于fun2()函数的参数是void*,所以还需要取这个对象的地址传入.
       fun2()其实可以直接用boost::shared_ptr<B>类型,就无须这样麻烦的转换,不过这样的话,就不能支持任意类型了.
    */
    boost::shared_ptr<B> pb(new B());
        
    /*
       这里不再需要关注thread的创建细节;
       boost::bind设计得太巧妙了;
    */
    boost::thread bthread(boost::bind(fun2, (void*)&pb));

    bthread.join();
}


int main()
{
    fun();
    cout << "FINISH" << endl;
}


上面的类型转换有点恶心,不过好在shared_ptr也是允许内部指针的类型继承的,好绕口.

还是看以下代码吧,B类由A类派生而来.所以boost::shared_ptr<A>这个类型,可以传递boost::shared_ptr<B>对象,并且由于shared_ptr重载了"->"符号,所以直接就可以访问B的成员了.




#include <boost/shared_ptr.hpp>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <string>


using namespace std;


class A
{
public:
        virtual void out() {cout << "A::out();" << endl;}
};

class B : public A
{
public:
    B() {cout << "construct B;" << endl;}
    virtual void out() { cout << "B::out();" << endl; }

    ~B(){ cout << "destroy B;" << endl;}
};



/*
  fun2 可以接收任何A类以及从A派生的类的shared_ptr对象.
  这样做,勉强也可算是支持任意类型了,因为只要传递的参数是从A派生即可.
*/
void* fun2(boost::shared_ptr<A> pa)
{
    // 不再需要任何转换,直接访问其子类的虚方法了.

    pa->out();
    sleep(10);
}

void fun()
{
    /*
       代码确实很简洁了.
    */
    boost::shared_ptr<B> pb(new B());
    boost::thread bthread(boost::bind(fun2, pb));

    bthread.join();
}

int main()
{
    fun();
    cout << "FINISH" << endl;
}

更多推荐

boost::shar

本文发布于:2024-02-10 13:25:23,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1675701.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:boost   shar

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!