在嵌入式系统中,经常会涉及资源共享或流程时序控制等需求,此时就需要在生产者与消费者之间,插入同步逻辑,以保证数据一致性和流程时序。下面就罗列了一些在裸机、rtos和linux下常用的同步手段。
一、裸机(无 OS 前后台架构)
同步手段 1:开关中断(屏蔽中断)
原理:进入临界区前关全局 / 局部中断,执行完再开中断
适用场景
同步手段 2:全局标志位 / 状态变量
原理:中断置标志,主循环轮询判断
适用场景
同步手段 3:忙等待(自旋轮询)
原理:while(!ready); 死等条件满足
适用场景
同步手段 4:内存屏障(编译器 / CPU 屏障)
原理:阻止编译器乱序、CPU 流水线乱序
适用场景
二、RTOS(FreeRTOS/RT-Thread/uC/ 鸿蒙轻量)
1. 二值信号量
场景:任务 ↔ 中断 同步、任务间事件唤醒
限制
2. 计数信号量
场景:资源池管理(串口、缓冲区、硬件资源)、生产者消费者
限制:无所有权概念,谁都能释放,容易误释放
3. 互斥锁 Mutex
场景:多任务独占共享资源(外设、全局结构体)
限制
4. 事件组 Event Group
场景:一个任务等待多个事件组合触发
限制
5. 消息队列
场景:任务间带数据同步 + 通信,生产者->消费者
限制
6. 挂起调度器(锁任务调度)
场景:保护较长临界区,不想关中断
限制
7. 中断专用同步(ISR 版信号量 / 队列)
场景:中断里唤醒任务
限制
三、Linux
(一)Linux 用户态 同步手段
1. 互斥锁 pthread_mutex
场景:多线程临界区互斥、共享变量保护
限制
2. 条件变量 pthread_cond
场景:线程等待某个条件满足(生产者 - 消费者)
限制
3. 读写锁 rwlock
场景:读多写少 场景(配置表、状态全局变量)
限制
4. 自旋锁 pthread_spinlock
场景:临界区执行极短,不想休眠切换线程
限制
5. 无名 / 有名信号量 sem_t
场景:多线程、多进程间同步
限制
6. 文件锁 flock/fcntl
场景:多进程对同一文件、资源互斥
限制
(二)Linux 内核态 同步手段
1. 自旋锁 spinlock_t
场景:SMP 多核、中断上下文、临界区很短
限制
2. 互斥锁 struct mutex
场景:进程上下文、临界区可睡眠、耗时较长
限制
3. 内核信号量 semaphore
场景:资源计数、进程间同步、可阻塞等待
限制
4. 关中断 + 自旋锁(spinlock_irqsave)
场景:防止任务与中断、多核同时竞争资源
限制
5. 完成量 completion
场景:内核异步等待(驱动等待硬件就绪、初始化完成)
限制:专用于一次性等待,不适合循环互斥
6. RCU 读写同步
场景:读极多、写极少 内核数据结构(路由表、设备链表)
限制
合理使用上述裸机、rtos和linux下的常用同步方法,就可以让资源共享,时序控制等程序变得丝滑起来。