读者朋友们——大家好!
先向大家道句——国庆快乐!前段时间挺忙的,分身无力,大家保重好身体。想要领到退休金,得先活到退休年龄!想薅退休金羊毛,可能是想多了~
国庆后,经过半年的试用期,终于转正了!工作也相对集中一些,今年最后两个多月,主要计划还是工作为主,继续锻炼身体,后面做美食的手艺还要重新捡起来!深圳这边工作还是累一些,每周至少要加班4.5个小时!4.5小时听起来不多,但是:且听我娓娓道来!
原则上周一、周二、周四需要加班。每天正常7.5工作小时,18:00下班,一般吃完饭遛会儿弯,到公司19:30左右,工作到21:00,可以领个夜宵;如果周三工作21:00,可以领水果……21:00离开公司,如果住的地方离公司远些,到家估计22:00了,再稍微收拾收拾,也就该就寝了,基本没有个人生活!工资就那样吧,年终奖要看绩效的,据说绩效是B,有3,但我觉得够呛。我来了半年,算项目经理,跑路4个了——问题不大,人才是流动的。越重要的事,越要投入时间思考,要不断修改模型。工作占据的时间多了,思考的时间便少了;工作时思考的多了,休息时便不想思考了;爱吃甜品是本能,少吃是对抗本能,另外也可能是老了,吃完不舒服……
回归正题——多线程的数据安全性!
很久以前,我有一个疑问——在回调函数中将数据拷贝到成员变量,其他函数使用这个变量的接口,是否是安全的?
如今回头看,可以明确的是,如果其他线程使用这个变量的函数接口,是不安全的。下面明确概念:
一、概念明确
1、C++ 标准层面:什么是“数据完整性”
C++17 §1.10.21 (C++20 §6.9.2, C++23 §6.9.2)
当两个线程访问同一个内存位置且至少一个是写操作,并且它们之间没有同步(如原子操作或锁)时,就是 data race(数据竞争),其行为是未定义的(undefined behavior)。
即:
多线程读同一个对象:安全(只读)。
一个线程写、另一个线程读:不安全(未同步则未定义)。
多个线程写:不安全。
2、基本类型(如 int, float, double)在 ARM 与 x86 下的行为差异
这块不展开,只留一个结论——所有跨线程共享且会写入的对象,必须使用 std::atomic 或外部同步机制。
3、STL 常用类型的线程安全性(来自 ISO C++ 标准 / cppreference)
STL 容器在 C++ 标准中几乎都规定「多线程读是安全的,写必须同步」。
实际测试: 在x86上一个线程memcpy更新数据,另一个线程memcpy读取数据,程序没有体现“数据撕裂”。
另外,为了通用化数据传递,使用uint8_t *buf, uint_16 size 与模板,哪种更高效呢?
对比项 | 模板传结构体 | 传指针 + size |
|---|---|---|
| 编译期开销 | 模板实例化增加编译时间,但一次性 | 无模板实例化,代码更通用 |
| 运行时效率 | ✅ 更快(几乎零额外开销):编译器完全知道结构体大小与布局,可 inline、寄存器优化 | ⚠️ 略慢:仅知道 |
| 类型安全 | ✅ 强类型、可静态检查 | ❌ 无类型信息,容易错配 |
| 内存拷贝 | 若函数参数是 | 同样可零拷贝(如果仅传指针),但通常调用者还得手动 |
| 数据对齐 | 编译器自动保证结构体对齐 | 调用者必须手动保证 |
| 跨平台可移植性 | 有字节序/对齐差异风险(需 serialize) | 同样有风险(但更明显) |
场景 | 推荐方式 | 理由 |
|---|---|---|
数据 < 1KB,频繁调用(高频控制/传感) | ✅ 模板传结构体 ( | 编译期优化彻底,零开销,类型安全 |
数据 >= 1KB 或动态格式 | ⚙️ 指针 + size | 结构体模板会导致大量实例化,二进制膨胀;此时内存带宽主导性能 |
需要跨进程或跨网络传输 | ⚙️ 指针 + size + 显式序列化 | 必须考虑字节序与对齐 |
仅模块内共享、实时性高 | ✅ 模板传结构体 | 最安全最快 |
欢迎关注:
10万+

被折叠的 条评论
为什么被折叠?



