业务经验
1.问题习题化,即规定输入和输出
2.拆解业务:去掉各种插件,最小化
3.出现一个问题,就考虑什么情况会出现这种情况,然后逆向推导一下保证只有最新的数据流会被转发
实现读取一次和读取多次的判断
mtxObj对象
写一个线程实现循环执行sendData函数转发:不可以定义为成员变量,因为父函数结束之后也会结束。
可以定义为静态的
自旋锁(Spinlock)是一种用于多线程编程的同步机制,它不会使线程进入睡眠状态,而是持续地检查锁的状态(自旋),直到获取到锁为止。这与传统的互斥锁(Mutex)不同,
互斥锁在无法获取锁时会将线程置于阻塞状态,等待锁被释放。
通常情况下,自旋锁适用于以下场景:
在多核处理器上运行的并行程序,因为自旋锁能够避免线程切换的开销。
在短时间内(临界区很小)对共享资源进行频繁访问的情况下,因为自旋锁的开销要比互斥锁低。
请注意,自旋锁适用于特定的场景,需要根据实际情况和需求来选择合适的同步机制。在一些情况下,使用互斥锁或其他更适合的同步机制可能会更好地实现线程同步。
mtxObj对象解析:
private定义:
自旋锁
uint_8 类
模板对象
public:
构造函数
set函数
get函数
一个=的重载
Lambda 表达式通常被视为匿名函数,可能在调试时难以追踪和定位问题。
建议在必要时将 Lambda 表达式提取为具名函数,以便更容易进行调试。执行外接脚本,限制本地文件大小
CloudPan/d78d2c2eb52dddbc1309859939a66c88373eec1e根据信号跳变进行业务
bool flag = false;
void isChange(uint8_t newSingle)
{
static uint8_t oldSingle = -1;
if ((oldSingle == 1 && oldSingle == 2) && (newSingle == 100))
{
flag = true; //消耗量,在其他模块设置为true,用完之后其他模块再设置为false;基于生产者消费者模型
}
oldSingle = newSingle;
}
同一文件内实现信号跳变
收到状态机信号后:,存储一个内部变量为stateMachine.signleLast
int main(){
isChange();
//others logic
updateStatic();
}
void updateStatic(){
stateMachine.signleLast = stateMachine.signle;
}
void isChange()
{
if ((stateMachine.signle == 1 && stateMachine.signleLast == 2))
{
return 0x05;
}
}同一文件内实现信号保持
收到状态机信号后:,存储一个内部变量为stateMachine.signleLast
class teset{
test();
~test();
private:
bool isKeep = false;
}
int main(){
isChange();
//others logic
updateStatic();
}
void updateStatic(){
stateMachine.signleLast = stateMachine.signle;
}
void isChange()
{
if(stateMachine.signle == 1){
isKeep = true;
}
if(stateMachine.signle != 1){//如果要有其他的不保持条件需要单独写成一个if
isKeep = false;
}
if ((stateMachine.signle == 1 && stateMachine.signleLast == 2)&&(isKeep&&(stateMachine.signle == 1)))
{
return 0x05;
}
}
### 定位问题
```C++
添加打印:不要只盯着最终的目标看,把每个相关联的函数头和尾都加上打印,串联起来:分段的思想:一个函数内部:上游,自己,下游,加打印调试
测试程序是否完成:不要只盯着最终的目标看,要对过程正确函数以固定的速率发送实现方式
函数以固定的速率发送实现方式
计算开始时间a;
函数处理;
计算结束时间b;
线程睡眠b-a时间
#include <iostream>
#include <chrono>
#include <thread>
void schedule_event(std::chrono::system_clock::time_point event_time) {
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
if (event_time > now) {
// 计算需要等待的时间
std::chrono::duration<double> wait_time = event_time - now;
// 等待相应的时间
std::this_thread::sleep_for(wait_time);
}
// 执行事件
std::cout << "Event executed at " << std::chrono::system_clock::to_time_t(now) << std::endl;
}
int main() {
// 计划在5秒后执行事件
std::chrono::system_clock::time_point event_time = std::chrono::system_clock::now() + std::chrono::seconds(5);
schedule_event(event_time);
return 0;
}判断数据相等16进制/8进制
判断不能用0x,因为0x表示的是8进制定时发送
控制发送频率:
while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
// 发送周期不要大于2S,因为MapFactory吐数据到AP接口有2秒超时机制,超时将恢复默认值
// 周期发送,1HZ
#if 0
brokerPlugin::pluginMsg outMsg;
sptrPlugin->fillNaviStateMsg(outMsg, navi_state.get());
loader->send(outMsg);
#endif
}信号防抖机制
防抖解决方案
设计思路: 进入某个状态容易,但退出需要更明显的变化。
举例说明:
进入近距离区:当 distance < 6m 时进入
退出近距离区:需要 distance > 7m 才退出
这样就形成了一个"滞回区间"[6m, 7m]:
在6m进入近距离区后
即使距离波动到6.5m,仍然保持在近距离区
只有超过7m才会退出到中距离区
为什么是这些具体数值?
进入: <6m 6-10m >10m
退出: >7m <5m||>11m <9m
这是为了在三个区间之间都建立缓冲带:
近↔中:6m-7m缓冲
中↔远:10m-11m缓冲
远↔中:9m-10m缓冲#include <iostream>
#include <vector>
enum DistanceZone { NEAR, MEDIUM, FAR };
DistanceZone updateDistance(double distance, DistanceZone& currentZone) {
switch (currentZone) {
case NEAR:
if (distance > 7.0) {
currentZone = (distance <= 10.0) ? MEDIUM : FAR;
}
break;
case MEDIUM:
if (distance < 5.0) {
currentZone = NEAR;
} else if (distance > 11.0) {
currentZone = FAR;
}
break;
case FAR:
if (distance < 9.0) {
currentZone = (distance < 6.0) ? NEAR : MEDIUM;
}
break;
}
return currentZone;
}
int main() {
DistanceZone zone = MEDIUM; // 初始状态
std::vector<double> distances = {8.0, 5.5, 6.2, 5.8, 6.1, 7.5, 10.5, 9.8, 11.5, 8.5};
for (double dist : distances) {
updateDistance(dist, zone);
std::cout << dist << "m -> Zone " << zone << std::endl;
}
return 0;
}