zoukankan      html  css  js  c++  java
  • linux下C++对线程的封装

    之前一直是使用C语言,前段时间转做C++。无论使用什么语言,多线程编程都是不可或缺的。最近项目中又用到了线程,现在将线程的封装做出总结:

    1、线程类中应该包含线程ID、线程的状态以及线程基本操作等。

    2、线程需要的基本操作都差不多,唯一不同的是线程执行的函数体。因此大多数操作都可以写在基类中,当需要使用线程时,只需要继承该基类并且实现run函数即可。

    基类的定义如下:

     1 /*线程基类,封装了线程常用的操作,以后需要使用线程时,只需要继承该类并实现Run函数既可*/
     2 class CThread {
     3 public:
     4 
     5     /*如果不需要为线程传参数,则可以使用这个构造函数*/
     6     CThread()
     7     {
     8         m_ThreadId = 0;
     9     
    10         m_iThreadStatus = 0;
    11     
    12         m_vpParameter = NULL;
    13     }
    14     
    15     /*重载构造函数,该构造函数可以为线程传参数*/
    16     CThread(void *vpParameter)
    17     {
    18         m_ThreadId = 0;
    19     
    20         m_iThreadStatus = 0;
    21         
    22         m_vpParameter = cpParameter;
    23     }
    24     
    25     virtual ~CThread();
    26 
    27     /*线程的启动函数,在该函数中将会创建线程*/
    28     int Start(void *Parameter);
    29 
    30     /*线程的回调函数,在该函数中只是转调run函数*/
    31     static void *ThreadCall(void *vpParameter);
    32 
    33     /*获取线程ID*/
    34     pthread_t GetThreadId()
    35     {
    36         return this->m_ThreadId;
    37     }
    38     
    39     /*获取线程状态*/
    40     int GetThreadStatus()
    41     {
    42         return m_iThreadStatus;
    43     }
    44     
    45     /*获取线程状态*/
    46     int GetThreadStatus();
    47 
    48     /*线程真正工作的函数,这个函数需要在派生类中实现*/
    49     virtual void *Run(void *Parameter) = 0;
    50 protected:
    51 
    52     //线程的Id号
    53     pthread_t m_ThreadId;
    54     
    55     //线程状态
    56     int       m_iThreadStatus;
    57     
    58     //线程参数
    59     void* m_vpParameter;
    60 };
    61 
    62 inline pthread_t CThread::GetThreadId()
    63 {
    64     return this->m_ThreadId;
    65 }

      在线程的回调函数中,只是转掉函数Run。这样设计的原因是因为在C++的回调函数必须是全局函数或者是静态成员函数,否则编译不会通过。而全局函数没有虚函数一说,也没有继承一说(静态函数也没有,静态函数只是限制了作用域的全局函数)。Start函数与线程的回调函数实现如下:

     1 int CThread::Start(void *vpParameter)
     2 {
     3     int ret = pthread_create(&(this->m_ThreadId), NULL, CThread::ThreadCall, vpParameter);//该函数中创建线程
     4     if(0 == ret)
     5     {
     6         return TRUE;
     7     }
     8 
     9     return FAULT;
    10 }
    11 
    12 void *CThread::ThreadCall(void *vpParameter)//线程回调函数
    13 {
    14     void *vpRet;
    15     CThread *pObj = static_cast<CThread *>(vpParameter);//将指针强制性转化成对象
    16 
    17 
    18     vpRet = pObj->Run(m_vpParameter);//调用线程正在执行的函数
    19 
    20     return vpRet;
    21 };

    总结:这样设计以后,程序中如果需要其它使用其它线程,可以继承该基类,然后实现Run函数即可。如果需要线程等待等操作则需要在里面添加内容。

  • 相关阅读:
    0615-temp-python web
    ResultSet 转ArrayList
    svn与git
    日期与时间
    springboot 注解
    函数式编程
    几个O
    springboot框架中的异步执行
    JDBC
    mysql 导出表结构
  • 原文地址:https://www.cnblogs.com/zxtp/p/4989613.html
Copyright © 2011-2022 走看看