C++在类中起线程示例

144 篇文章 6 订阅

由于前面对线程不太了解,这几天要写插件管理框架。由于每个插件加载进来后必须起线程,让每个插件单独运行在一个线程内,才能保证所有插件都能并行执行,否则前面的线程执行完后面的才能执行,会造成阻塞。所以调研了一大堆资料,最后实现了在类内部启动线程执行用户逻辑。

最后将实现的所有代码和配置贴到这里,以供后面参考。

a.h定义了基类,纯虚函数,没有对应的cpp文件。

#ifndef __H_A_H__
#define __H_A_H__
#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include <thread>
namespace xxx_label_gen{
  using namespace std;

  class Parent
  {
    public:
      int i;
      std::thread t;
  public:
      virtual void print() { }
      virtual void startThread(){}
      virtual void createThread(){}
      virtual void setI(int j){}
      virtual int getI(){}
  };
}

#endif

b.h和c.h是子类,各增加了一个成员变量和对应的函数,都有对应的cpp文件,在cpp文件中声明为插件(如果是单独测试线程,则可以不注册成插件,把class_loader相关的内容删掉)。

//b.h

#ifndef __H_B_H__
#define __H_B_H__
#include "a.h"
#include "class_loader/class_loader.h"
//class_loader/class_loader.h >

#include <random>
namespace xxx_label_gen{
    using namespace std;
    
    class Child : public Parent  
    {
        int j; 
        
    public:
            void print()
            {
                cout<<"class Child"<<endl;
            }   
            void createThread();
            void startThread(); 
            int getJ();
            void setJ(int k);
            int getI();
            void setI(int s); 
    };
}
#endif
//c.h
#ifndef __H_C_H__
#define __H_C_H__
#include "a.h"
#include <random>
#include "class_loader/class_loader.h"
namespace xxx_label_gen{
    using namespace std;
    class Child2 : public Parent  
    {
        int k; 
    public:
            void print()
            {
                cout<<"class Child2"<<endl;
            }     
        // void createThread(void *arg);
            void createThread();
            void startThread();
            int getK();
            void setK(int k);
            int getI();
            void setI(int s); 
    };
}
#endif
//b.cpp
#include "b.h"
namespace xxx_label_gen{
  /*
  void Child::createThread(void *arg){
    Child * tmp = (Child*) arg;
    while(tmp->getI()!=1){
      sleep(2);
      tmp->setJ(random());
      printf("j=%d\n",tmp->getJ());
    }
  }*/
  void Child::createThread(){
  // Child * tmp = (Child*) arg;
  printf("in the child::createThread(), and i =%d\n",i);
    while(i!=1){
      sleep(2);
    j = random();//修改Child的public类型的成员变量j
      printf("j=%d\n",j);
    }
    printf("in the end of the child::createThread()\n");
  }

  void Child::startThread(){
    //t = new std::thread(&createThread,this);
    i = 50;
    printf("in the child::startThread()!\n");
    t = std::thread(&Child::createThread,this);
    t.detach();

  /* 这段代码会造成createThread()一直在执行,在调用该函数的地方的后续代码都无法执行,所以这里不能使用while()
    while(i--){
      sleep(2);
      printf("current j=%d\n",j);
    }
    */
    /*if(t.joinable())  t.detach();
    while(i--){
      sleep(1);
    }
    sleep(5);*/
  }

  void Child::setI(int j)
  {
    i = j;
  }

  int Child::getI(){
    return i;
  }

  void Child::setJ(int k)
  {
    j = k;
  }

  int Child::getJ(){
    return j;
  }
 }

 CLASS_LOADER_REGISTER_CLASS(xxx_label_gen::Child, xxx_label_gen::Parent)
#include "c.h"
CLASS_LOADER_REGISTER_CLASS(xxx_label_gen::Child2, xxx_label_gen::Parent)//不制作插件的话,删掉上面的句子

namespace xxx_label_gen{
  /*
  void Child2::createThread(void *arg){
    Child2 * tmp = (Child2*) arg;
    while(tmp->getI()!=1){
      sleep(3);
      tmp->setK(random());
      printf("k=%d\n",tmp->getK());
    }
  }*/
  void Child2::createThread(){
    //Child2 * tmp = (Child2*) arg;
    while(i!=1){
      sleep(3);
      k = random();//修改Child2的public类型的成员变量k
      printf("k=%d\n",k);
    }
  }

  void Child2::startThread(){
    i = 100;
    t = std::thread(&Child2::createThread,this);
    t.detach();
    //if(t.joinable())  t.detach();
    /* 这段代码会造成createThread()一直在执行,在调用该函数的地方的后续代码都无法执行,所以这里不能使用while()
    while(i--){
      sleep(3);
      printf("current k=%d\n",k);
    }*/
  }

  void Child2::setI(int j)
  {
    i = j;
  }

  int Child2::getI(){
    return i;
  }

  void Child2::setK(int j)
  {
    k = j;
  }

  int Child2::getK(){
    return k;
  }
 }
//main.cpp
#include "b.h"
#include "c.h"

using namespace std;
using namespace xxx_label_gen;
int main()
{
   Child c1;
   Child2 c2;
   // std::thread t1(std::bind(&Child::createThread),&c1,&c1),t2(std::bind(&Child2::createThread,&c2,&c2));
    Parent *t, *t2; 
   t = new Child();
    
    t->print();     
    t->startThread();//启动线程
    
    cout<<"SIZEOF Parent:"<<sizeof(t)<<endl;

    t2 = new Child2();
    t2->print();
    t2->startThread();
    //下面保留一个延迟函数,确保main线程不会结束,否则前面创建的2个线程会随着main线程的结束而退出!
    getchar();
   cout<<"main thread exit()\n"<<endl; 
}

CMakeLists.txt

cmake_minimum_required (VERSION 2.6)
  project (classtest) 

include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread")
elseif(COMPILER_SUPPORTS_CXX0X)
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
     message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()

set(${PROJECT_NAME}_HDRS
  include/a.h
  include/b.h
  include/c.h
)
  include_directories (include "${PROJECT_SOURCE_DIR}/include")

  FILE(GLOB SRC_LIST_CPP "${PROJECT_SOURCE_DIR}/src/*.cpp")
  FILE(GLOB SRC_LIST_C "${PROJECT_SOURCE_DIR}/src/*.c")


set(LINK_DIR /home/ok/code/code/classtest/lib )
set(CONSOLE_DIR /lib/x86_64-linux-gnu/)

link_directories(${LINK_DIR} ${CONSOLE_DIR})

  add_executable (main test/main.cpp src/b.cpp src/c.cpp)

如果要生成class_loader能用的插件,则上面CmakeLists要增加一点内容,最终生成lib/*.so

cmake_minimum_required (VERSION 2.6)
  project (classtest) 

include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread")
elseif(COMPILER_SUPPORTS_CXX0X)
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
     message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()

set(${PROJECT_NAME}_HDRS
  include/a.h
  include/b.h
  include/c.h
)
  include_directories (include "${PROJECT_SOURCE_DIR}/include")

  FILE(GLOB SRC_LIST_CPP "${PROJECT_SOURCE_DIR}/src/*.cpp")
  FILE(GLOB SRC_LIST_C "${PROJECT_SOURCE_DIR}/src/*.c")


set(LINK_DIR /home/ok/code/code/classtest/lib )
set(CONSOLE_DIR /lib/x86_64-linux-gnu/)

link_directories(${LINK_DIR} ${CONSOLE_DIR})

  add_executable (main test/main.cpp src/b.cpp src/c.cpp)

#  link_directories(${LINK_DIR} ${CONSOLE_DIR})
#  link_libraries(class_loader console_bridge)
  target_link_libraries( main optimized
    libclass_loader.so
    libconsole_bridge.so

 )

  add_library(test SHARED ${SRC_LIST_CPP} ${${PROJECT_NAME}_HDRS})
    target_link_libraries( main optimized
    libclass_loader.so
    libconsole_bridge.so

 )

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值