C++ thread的方式

5 篇文章 0 订阅
4 篇文章 0 订阅

多线程的实现方式,只做记录,自己看。

第一种 在类中实现多线程

新建thread对象,传入类的成员函数名称,对象地址,以及成员函数需要的参数。

在类的成员函数中,要实现多线程
 void Perception::test()
 {
 		.....
 		thread th( &Perception::showImage, this);  //实例化一个线程对象th,使用函数t构造,然后该线程就开始执行了( &Perception::showImage)
 		.....
 		}
 void Perception::showImage();
 如果showImage()要传参数,就在this后面加上。

如果Perception中有另外一个成员,叫做mapOptimization,如果线程函数是mapOptimization的成员函数,

LidarMapping::mapOptimization::loopClosureThread

unique_ptr loopThread = std::make_unique<std::thread>(&mapOptimization::loopClosureThread,this->MO_);
会出问题
 要把mapOptimization::loopClosureThread 封装成LidarMapping 的一个函数loopClosure:
 loopThread = std::make_unique<std::thread>(&LidarMapping::loopClosure,this);

第二种 在类外

在主函数中,

void main()
{
	A a;
	thread th(&A::test,&a);
	// 如果要传参数,就在&a后面加上。
}

第三种 没有类

void func()
{
	.....
}
void main()
{
	A a;
	thread th(func);
	// 如果要传参数,就在&a后面加上。
}

第四种 pthread,定时触发

使用定时器触发,传入多个参数。
定时器实现是在回调函数中的:

 		double process_time = double(clock() - time_start) / CLOCKS_PER_SEC * 100;
        // ROS_ERROR_STREAM(" process_time......"<< process_time);
        pthread_testcancel();
        struct timeval tempval;
        tempval.tv_sec = 0;
        tempval.tv_usec = 100000; // 10hz
        select(0, NULL, NULL, NULL, &tempval);

其中,多个参数的定义在TIMECALL(结构体),先对结构体成员进行实例化、赋值,然后在将timecall(取地址)传入。

    TIMECALL timecall;
    timecall.log = &log_data;
    timecall.outdata = &serial_output;
    timecall.udp_output = &udp_output; // 20220801 yuphe  需要设置UDP
    timecall.threadPerception = &per;  // 20220801 yuphe  获取数据
    timecall.m_LogFile = &file_check;     // 20221102 yuphe  日志内存检测
void main()
{
	TIMECALL timecall;
    timecall.log = &log_data;
    timecall.outdata = &serial_output;
    timecall.udp_output = &udp_output; // 20220801 yuphe  需要设置UDP
    timecall.threadPerception = &per;  // 20220801 yuphe  获取数据
    timecall.m_LogFile = &file_check;     // 20221102 yuphe  日志内存检测
    // timecall.m_RosLog  = 


    pthread_t id;
    int i, ret;
    ret = pthread_create(&id, NULL, thread_cb, (void *)&timecall);
}


typedef struct TIMECALL_
{
    Log *log;
    result_serial::perception_result_serial *outdata;
    UDPSocket *udp_output = nullptr; // yuphe 20220801

    perception::Perception *threadPerception = nullptr; // yuphe 20220801
    
    FileManage *m_LogFile= nullptr; //增加内存检测 20221102 
    FileManage *m_RosLog = nullptr; //增加ROS日志检测 20221102 

} TIMECALL;

void *thread_cb(void *p) // void *serialOut
{
    TIMECALL *arg = (TIMECALL *)p;
    clock_t time_start = clock();
    while (true)
    {

        // sizeof(Perception_output_proto) 346
        perception_output = arg->threadPerception->getOutdata();
        // print out data
        // for (int i = 0; i < 20; i++)
        // {
        //     std::cout << "OBJECT:" << i 
        //               << " ID = " << ((int)perception_output.proto_objects[i].NoID) 
        //               << " Pos = (" << (((double)perception_output.proto_objects[i].x) / 100) << " , " << (((double)perception_output.proto_objects[i].y) / 100) 
        //               << ") Size = " << (((double)perception_output.proto_objects[i].L) / 100) << " X "
        //               << (((double)perception_output.proto_objects[i].W) / 100) << " X " 
        //               << (((double)perception_output.proto_objects[i].H) / 100) << std::endl;
        // }
        // std::cout << ((int)perception_output.proto_sys_status
        // print out data end

        // yuphe 20220801
        arg->udp_output->UDPSocket::Send((char *)&perception_output, sizeof(perception_output));
        arg->log->toFile((unsigned char *)&perception_output, sizeof(perception_output));
        arg->m_LogFile->Start();//增加内存检测 20221102 
        // arg->outdata->callback_track_sub(*(arg->log), Sensor_state, System_state,my_version);

        double process_time = double(clock() - time_start) / CLOCKS_PER_SEC * 100;
        // ROS_ERROR_STREAM(" process_time......"<< process_time);
        pthread_testcancel();
        struct timeval tempval;
        tempval.tv_sec = 0;
        tempval.tv_usec = 100000; // 10hz
        select(0, NULL, NULL, NULL, &tempval);
    }
}

总结

1.形式都是类似的,定义thread,然后在构造函数或者pthread_creat函数中将要处理的函数及参数放进去
2.pthread要放静态函数。对于静态函数的处理,尤其是对于类的非静态成员函数的处理要留意,这部分后续补充。目前采用的办法是thread th(&类名::函数名,对象地址,参数)的方式。
3.之前做java的时候,好像是继承Thread类,重写run函数,还有runable接口,好像在C+里面不怎么使用这种方式,后续遇到再补充。

附录

几篇博客:
C++多线程的实现
C++多线程详细讲解
C++ 多线程编程之在类中使用多线程(thread)的方法
C++多线程编程之thread类
C++ 在类里面使用多线程技术

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值