来源:https://github.com/HeYijia/VINS-Course
参考:VINS-Mono代码精简版代码详解-无ROS依赖(一)_jiweinanyi的博客-CSDN博客
0 前面定义
std::shared_ptr<System> pSystem;
智能指针,参考c++ primer P400
shared_ptr是智能指针的一类,用于管理动态对象,允许多个指针指向同一个对象。
<>内给出指向的类型,之后是所定义的这种智能指针的名字。
上述语句的意思为:指向System类的智能指针 pSystem
1. 主函数
1. argc函数和argv函数
参考:C++ main函数中参数argc和argv含义及用法_牧野的博客-CSDN博客_argc argv
argc 是 argument count的缩写,表示传入main函数的参数个数;
argv 是 argument vector的缩写,表示传入main函数的参数序列或指针,并且第一个参数argv[0]一定是程序的名称,并且包含了程序所在的完整路径,所以确切的说需要我们输入的main函数的参数个数应该是argc-1个;
if(argc != 3)
{
cerr << "./run_euroc PATH_TO_FOLDER/MH-05/mav0 PATH_TO_CONFIG/config \n"
<< "For example: ./run_euroc /home/stevencui/dataset/EuRoC/MH-05/mav0/ ../config/"<< endl;
return -1;
}
sData_path = argv[1];
sConfig_path = argv[2];
char *a[] 表示一个数组,数组中的元素才是char * (即元素是指向char类型的指针)。
char **s 为一个二级指针,s中保存的是一级指针char *的地址。可以这么来理解char *(*s),我定义一个指针s,但是我指针s保存的不是传统某个变量的地址,而是保存的是一个char * 指针的地址。(把char理解为a,char *理解为b,char**理解为c。那么b的值是a的地址,然而c的值又为b的地址)
2. reset 函数
sData_path = argv[1];//run euroc
sConfig_path = argv[2];//数据集路径
pSystem.reset(new System(sConfig_path));
p是智能指针对象,
p.reset(q) //q为智能指针要指向的新对象,会令智能指针p中存放指针q,即p指向q的空间,而且会释放原来的空间。(默认是delete)
new运算符:在动态内存中为对象分配空间并返回一个指向该对象的指针,我们可以选择对对象进行初始化
3 std::thread 函数
std::thread thd_BackEnd(&System::ProcessBackEnd, pSystem);
// sleep(5);
std::thread thd_PubImuData(PubImuData);
std::thread thd_PubImageData(PubImageData);
#ifdef __linux__
std::thread thd_Draw(&System::Draw, pSystem);
#elif __APPLE__
DrawIMGandGLinMainThrd();
#endif
thd_PubImuData.join();
thd_PubImageData.join();
// thd_BackEnd.join();
#ifdef __linux__
thd_Draw.join();
#endif
std::thread t1(func);
定义了一个线程t1,括号里面的参数就是你要线程去执行的函数。
std::thread t1(func,args);
定义了一个线程t1,以args为参数,执行func函数。
this_thread::sleep_for();//就是让此线程休眠,可以传入休眠的时间
this_thread::sleep_for(std::chrono::milliseconds(10));//让本线程休眠10毫秒
参考:c++11 多线程入门教程(一) - aircraft - 博客园
C++11 多线程(std::thread)详解_sjc_0910的博客-CSDN博客_c c++ 多线程
问题:无论创建多少个线程,他们都可以同时运行嘛?在不结束他们的前提下
4 #ifdef #elif #endif 的用法
参考:C++中 #ifdef 和#endif的作用_指尖飞舞-CSDN博客_c++ endif
一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是“条件编译”。有时,希望当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。
条件编译 命令 最常见的形式为:
#ifdef 标识符
程序段1
#else
程序段2
#endif它的作用是:当标识符已经被定义过(一般是用#define命令定义),则对程序段1进行编译,否则编译程序段2。
其中#else部分也可以没有,即:
#ifdef
程序段1
#denif
5 总结:主函数意思
pSystem.reset(newSystem(sConfig_path)); //基于输入的数据集路径创建一个新的System类:pSystem
std::thread thd_BackEnd(&System::ProcessBackEnd, pSystem); //创建一个后端线程 thd_BackEnd,这个线程是将pSystem类用于ProcessBackEnd函数
std::thread thd_PubImuData(PubImuData); //创建线程:用于imu数据的发布
std::thread thd_PubImageData(PubImageData); //创建线程:用于图像数据的发布
#ifdef__linux__ //如果是linux系统,就创建线程thd_Draw:用于画图,如果是苹果系统,就执行函数
std::thread thd_Draw(&System::Draw, pSystem);
#elif__APPLE__
DrawIMGandGLinMainThrd();
#endif
thd_PubImuData.join(); //等待发布imu数据的线程结束,并清理资源
thd_PubImageData.join();//等待发布图像数据的线程结束,并清理资源
//thd_BackEnd.join(); //等待后端的线程结束,并清理资源
#ifdef__linux__
thd_Draw.join();
#endif