Linux相关:
- find . -name "*.c"来寻找在本文件夹下所有.c类型的文件。
- 在.sh脚本后面加 & 表示该脚本在后台运行。
- 一个大的项目的启动可以写多个.sh脚本,在最外层调多个.sh脚本并使其运行在后台 &,这样可以让多个.sh并行。在最后使用wait等待多个.sh运行同步。
- 使用if可以完成在shell脚本中的判断,将条件放置在中括号中,例如
if [ $(lsof -i udp:10020 -t) -gt 0 ];then
sudo kill -9 $(lsof -i udp:10020 -t)
fi
- 可以实现kill占用10020端口的进程。
- linux.sh脚本中#!/bin/bash和#!/bin/sh脚本是两种脚本,后者没有source命令。
- ping -c 后面可以指定ping的次数。
C++相关:
- 条件编译和宏编译:
- #if 1 和 #endif 可以来进行条件编译,判断1这个位置的表达式的值是否为真。
- 条件编译选项 #ifdef [] 和 #endif 是检测是否有 [] 内的标志被 #define。
- 其中一些 #define [] 是一些空define,但是可以作为类似Java中注解的作用。
- C++ 中的结构体也有this关键字,但是其类型为指针,可通过this->来取出内的成员。在构造函数赋值时用处很大。
- 函数指针的定义为:[返回类型] (* [函数名]) ([型参])。
- typedef int (*fPointer)(void); 定义的是一个函数指针。这样我们就可以使用 fPointer 来定义一个函数指针。比如我们使用 fPointer fp 声明函数指针就如同使用 int (*fp)(void) 来声明。
- (void *) data 定义的是一个void类型的指针,void 指针可以指向任意类型的数据,就是说可以用任意类型的指针对 void 指针赋值
- 使用extern关键字:
- 引用同一个文件中的变量,若变量在使用处后定义,会出现变量未定义的报错。这样就可以定义extern [变量定义]放在该变量使用之前。这样就提前声明了该变量在本文件的其他地方进行了声明,让编译器去后面自己找。
- extern还可以引用其他文件中的变量,这样不用include对所有的变量和函数进行一个引入。而是引入了在别的文件中定义的一个全局变量。
- extern的真实场景中的作用是对一些保密算法进行一些隐藏。只在头文件中进行extern。但是真实的定义是在隐藏的.so文件中。
- 头文件更多的是给别人看的,说明行文档。对于计算机来说没有什么作用。
- 当多个文件进行集成的时候,可能会出现typedef冲突,解决方法是在出现冲突的头文件上下使用#define uint8 [项目]_uint8 #undef 进行包裹,这样在包裹范围内的代码会对重复的uint8等冲突的类型进行宏定义全局替换,就避免了冲突的发生,是一种十分巧妙使用宏定义的方法。
- Cmakelist是简化cmake的一个工具性文件。其中.so作为动态连接文件可以放在link_directories中进行声明,但是可能会从出现的问题是link_directories中的文件顺序会影响链接的结果,如果顺序不对可能出现依赖不能链接正确的问题。
- Cmakelist中比较重要的需要修改的几个参数有:
- include_directories(这个里的路径是头文件地址,扫描后获得所有的头文件)
- link_directories(这个是链接库的地址,如果有so等库文件需要将地址在这里声明)
- add_executable(这个是参与编译的cpp需要在这里面声明)
- add_library
- target_link_libraries(这个负责链接相关的配置,so等链接库文件需要在这里声明,同时需要注意顺序问题,)
- C++中的一个经典库为Boost库,是在C++标准的基础上添加了一些常用功能。可以参考官方文档:http://zh.highscore.de/cpp/boost/
- 在处理单个文件中执行顺序问题时,可以加简单的锁来实现,即定义几个信号量,通过volatile来实现简易的锁,但是这样的锁的信号量是在同一个工程内的,若跨工程会导致内存无法跨进程进程访问,这样可能需要进程间通信来解决。
- 同一工程内跨文件访问变量大部分都可以通过extern关键字来实现,即全局变量可通过extern来寻找到。
- 在工程设计上,能简单就别太复杂。
- 减少耦合的方法常常是把文件拆解出来,将一个大文件拆成多个功能文件。同时公共的变量可以单独放到.h文件中,这样引用可以最大程度减少冲突。
- 全局变量可以在名称定义前加上一个g来进行区分,也更容易识别。
- C++中的锁std::mutex
- 申请一个std::mutex类型的变量之后,该变量中lock()方法会尝试给该线程上锁,若获取锁不成功将会将该线程阻塞。在执行完成后,使用unlock()方法释放锁,不然会可能出现死锁。
- std::mutex是可能出现死锁的不太安全的锁,因为为当该类型的锁上锁之后在后续中该线程抛出error会导致锁一直不会释放,出现死锁。解决方法是使用更加安全的锁类型。
- std::mutex中的try_lock()方法会尝试上锁,并返回一个bool类型,来告诉是否获取锁成功。
- std::mutex可以在一个进程中多个线程间保持同步。
- 如果不想要使用比较重的锁的话可以使用一个共享的bool信号量和置true,false并在加锁区域之前进行while循环判断等待来实现。
- 在面向过程编程中一个很重要的一个关键字就是extern。该该关键字类似面向对象编程中的多态实现了多个文件共享函数的操作,实现功能模块的拆分。
- 很多项目和工程中,一些公共代码需要重复使用,这些代码会被编译成库文件,库文件包括静态库和动态库文件两种。在windows平台下,静态链接库是.lib文件,动态库文件是.dll文件。在linux平台下,静态链接库是.a文件,动态链接库是.so文件。
- 常见的构建系统
- CMake:是一个跨平台构建系统生成器。项目使用独立于平台的文件指定其生成过程。用户通过使用CMake为其平台上的本机工具生成构建系统来构建项目。
- Python setuptools:是Python包的打包常用工具。Python 包使用文件来描述依赖项,以及如何构建和安装内容。在ROS2中,功能包可以是“普通”Python包,而在ROS1中,任何Python功能都是从CMake文件触发setup.py进行打包。
- catkin:基于CMake,并提供了一组方便的函数,使编写CMake包更容易。它自动生成 CMake 配置文件以及 pkg 配置文件。它还提供了注册不同类型测试的函数。
- 常见的构建工具
- catkin_make:该工具仅调用 CMake 一次,并使用 CMake 的函数在单个上下文中处理所有包。虽然这是一种有效的方法,因为所有包中的所有目标都可以并行化,但它具有明显的缺点。由于所有函数名称、目标和测试都共享一个命名空间,并且规模更大,这很容易导致冲突。
- colcon:是一个命令行工具,用于改进构建,测试和使用多个软件包的工作流程。它自动化了流程,处理了订购并设置了使用软件包的环境。
- ament_tools:由用于构建 ROS 2 包的独立 Python 3 包提供。它是为引导ROS 2项目而开发的,因此仅针对Python 3,并且可以在Linux,MacOS和Windows上运行。
- 对于函数传参来说,传指针是最好的方法,因为这样不会进行拷贝工作,节省了时间和空间,但是指针操作常常可能出现危险,这样使用const int & x作为形参会更加好,因为这样的形参定义是一个x的引用,也不会出现拷贝,同时const int 保证x是一个常量,不会在函数内发生修改。
- C++中的thread的join操作其实只是在阻塞main线程的结束,在一个thread初始化时就开始执行了,只不过join是防止main线程未等待子线程执行完毕后就退出,将main线程阻塞。
- 同时线程的join操作是保证等待该线程执行完毕后在进行该线程join之后的语句。
宝藏链接
https://vuepress.mirror.docker-practice.com/introduction/what/ Docker学习
http://fishros.org:5000/ 自动文章封面生成