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

转载 2014年07月11日 11:11:27


原文链接: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++库中。



C++封装线程类

/** \file * Thread.h,定义线程创建和停止接口,通过内联函数提供给其它模块使用 * * \author Fzuim * * 版本历史 * \par 2014-7-7 * * * ...
  • fzuim
  • fzuim
  • 2017年04月10日 16:05
  • 341

C++线程锁封装

C++线程锁的封装,主要提供lock,unlock,require等操作,需要注意的是线程重复获取锁的问题,设置了一个count的计数器,该计算器之所以不考虑++,--的原子操作的问题,是因为该计数器...
  • turkeyzhou
  • turkeyzhou
  • 2013年02月22日 18:20
  • 2241

c++封装多线程类

编程实例: CThread.h #include #include #include #include class Runnable { public: virtual ~Runna...
  • chinabhlt
  • chinabhlt
  • 2015年11月18日 14:19
  • 1460

C++ 线程池的封装实现

为了充分利用多核的优势,我们利用多线程来进行任务处理,但线程也同样不能滥用,会带来一下几个问题: 1)线程本身存在开销,系统必须为每个线程分配如栈,TLS(线程局部存储),寄存器等。 2)线程管理...
  • turkeyzhou
  • turkeyzhou
  • 2013年04月03日 14:57
  • 31802

C++多线程面向对象解决方案

相信很多人都读过《C++沉思录》这本经典著作,在我艰难地读完整本书后,留给我印象最深的只有一句话::“用类表示概念,用类解决问题”。关于多线程编程,如果不是特别需要,大多数开发人员都不会特意去触碰这个...
  • zhuweisky
  • zhuweisky
  • 2005年07月05日 12:04
  • 3104

C++封装DLL的方法

一、首先,使用vs2008创建windows32控制台程序,点击“下一步”选择dll复选框,同时可以选择空项目(所有项目都自己写),确定 二、定义需要用到的头文件和源文件// header.h ...
  • u010769715
  • u010769715
  • 2015年06月04日 22:28
  • 2870

c++基于对象的编程风格2

知识点: 1.iterator的定义inline Triangular_iterator& Triangular_iterator:: operator++() { // prefix inst...
  • newbieLCQ
  • newbieLCQ
  • 2017年02月12日 15:36
  • 203

linux C++ 面向对象线程类(封装,继承,多态)

头文件Thread.h#ifndef _THREAD_H_ #define _THREAD_H_ #include //抽象类 class Thread { public: Thread();...
  • u011676589
  • u011676589
  • 2013年08月15日 09:19
  • 2502

C++线程的高级封装, 支持对类成员函数开启线程

  • 2014年04月16日 07:10
  • 2KB
  • 下载

c++11 thread 封装线程类

c++ thread也挺好用的,也可以像qt thread那样,start启动,run函数为线程的实际运行代码。thread和this_thread方法不多,常用的就几个。 1.std::t...
  • eric0095
  • eric0095
  • 2016年01月21日 11:01
  • 1311
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++中面向对象和基于对象的线程封装方法
举报原因:
原因补充:

(最多只允许输入30个字)