关闭

C++中面向对象和基于对象的线程封装方法

标签: 线程面向对象对象Boost
1538人阅读 评论(0) 收藏 举报
分类:


原文链接:http://blog.chinaunix.net/uid-26611383-id-4273854.html


文章开头我想发几句牢骚,也算是对过去几个月的总结,有好几个月没有来更新博客了,这期间发生了很多事情,换工作,接触新的项目,这几个月工作压力有些大,现在算是完成了一个小项目的第一个阶段,在这期间还是学到不少东西。对C++的理解增加了不少,以前很少用,虽然很喜欢,不过只是偏重于理论,C++确实博大精深,现在也只是懂了个皮毛。很高兴我对C++,对Linux很感兴趣,对现在的工作内容还是比较满意的。从500强的外企义无反顾的离职,降薪来到一家创业公司还是值得的,我觉得人应该首先要知道自己想要什么,自己喜欢什么。这里我想对还没有毕业或者即将毕业的朋友们说,不要在乎公司的光环,别人觉得好的不一定适合你,不要在乎刚开始比同学少拿那几百几千块钱,当你觉得整天上班只是一个工具,做着自己讨厌的事情,那种感觉简直生不如死。那些能让你得到锻炼并快速成长而且是你自己喜欢的工作才是真正适合你的工作,几年之后你会发现那几百几千块钱实在太微不足道。

这段时间看了不少C++代码,也写了一个小项目,这篇文章来说一下我见到过的比较通用的两种多线程封装方式,实现平台为Linux
首先说说地一种线程封装方式,也是我们平常见得最多的一种封装方式,是用面向对象中的继承,多态来实现的,下面来看具体的代码,这些代码使我随手写的,主要是为了说明思想,如果要用到项目中还需要完善。
    /*************************************************************************
        > File Name: Thread.cpp
        > Author: KevinFu
        > Mail: kevinfu1985@gmail.com
        > Created Time: 2014年05月26日 星期一 21时27分51秒
     ************************************************************************/

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


    using namespace std;

    class Thread
    {
    public:
        Thread(string name = "Unknown")
        {
        }
        virtual ~Thread()
        {

        }

        void Start()
        {
           pthread_create(&m_ThreadID, NULL, ThreadFunc, this);
        }

        static void* ThreadFunc(void* pth)
        {
            Thread* p = static_cast<Thread*>(pth);
            p->Run();
        }

        virtual void Run() = 0;

    private:
        pthread_t m_ThreadID;
    };


    class Test:public Thread
    {
    public:
        virtual void Run()
        {
            while(1)
            {
                cout<<"In Test::Run()"<<endl;
            }
        }
    };
    int main()
    {
        Thread* thread1 = new Test();
        thread1->Start();
        sleep(1);
    }


这里我们用Thread这个类来实现线程的封装,用户自己要启用的线程类都要继承这个Thread类,在Thread类的Start函数里,调用了pthread_create创建了一个线程,并将ThreadFunc设置为线程函数,把线程的this指针传递给了这个函数,在这个线程函数里调用了
虚函数Run,这个Run函数最终会利用多态调用到用户线程类的Run函数,这就是上面代码的基本原理,比较简单,这也是面向对象用的比较多的地方,也可以说是他的强大的地方,不过用起来比较别扭,我们公司的关于线程的封装就是用的这种方法,个人感觉很麻烦,不好用,用户要想启用一个线程,必须要继承Thread这个类,而且要覆盖Run这个虚函数,很麻烦。

下面这种线程封装方式是用基于对象的封装方式,上面的封装方式是面向对象的,这种方式我们用到了boost库中的神器boost::function, boost::bind,这个神器原理就是帮定一个函数对象,函数对象可以包含参数,我们可以利用这个神器调用任意全局函数,甚至类的成员函数,
而不需要继承自任何类,下面来看具体代码
    /*************************************************************************
        > File Name: Thread.cpp
        > Author: KevinFu
        > Mail: kevinfu1985@gmail.com
        > Created Time: 2014年05月26日 星期一 20时41分07秒
     ************************************************************************/

    #include<iostream>
    #include <pthread.h>
    #include <boost/function.hpp>
    #include <boost/bind.hpp>

    using namespace std;

    class Thread
    {
        typedef boost::function<void(void)> ThreadFunctionCallBack;
    public:
        Thread(ThreadFunctionCallBack cb, string name = "Unknow")
            :m_cb(cb)
        {
        }
        ~Thread()
        {

        }

        void Start(void)
        {
            pthread_create(&m_ThreadID, NULL, ThreadFunction, this);
        }

        static void* ThreadFunction(void* obj)
        {
            Thread* thread = static_cast<Thread*>(obj);
            thread->m_cb();
        }

    private:
        ThreadFunctionCallBack m_cb;
        pthread_t m_ThreadID;
    };

    class Test
    {
    public:
        void run(void)
        {
            cout<<"In test::run()"<<endl;
        }
    };

    int main()
    {
        Test t;
        Thread thread1(boost::bind(&Test::run, &t));
        thread1.Start();
        usleep(100);
    }


我们可以看到Test类不需要继承自Thread类,我们直接可以将boost::bind帮定的函数对象传递给Thread的构造函数,这里为了简单我们把this指针传递给了ThreadFunc,我们完全可以传递任何参数给ThreadFunc, 因为我们不需要使用多态,这就是基于对象的思想,比面向对象似乎更直接,使用起来更方便,更简单。

C++11中的tr1中已经包含了boost这两大功能,boost确实是代表着最高水平的C++库,其中有很多东西值得学习,也有很多东西即将加入到标准C++库中。



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:113288次
    • 积分:1543
    • 等级:
    • 排名:千里之外
    • 原创:8篇
    • 转载:145篇
    • 译文:1篇
    • 评论:4条
    最新评论