## 同步原语:互斥锁 vs. 自旋锁 选择合适的同步原语对性能至关重要。互斥锁和自旋锁都能保护临界区,但失败方式相反:互斥锁会*休眠*(引入系统调用开销),而自旋锁会*消耗 CPU* 等待。 自旋锁在用户空间使用原子比较交换操作,避免了系统调用,但会持续占用 100% CPU,直到锁可用。 这会导致缓存行在核心之间跳动,浪费能量。 互斥锁利用 `futex()` 系统调用,当出现竞争时会导致上下文切换和调度器参与。 自旋锁在支持抢占的系统中很危险——持有自旋锁的被抢占线程可能导致其他线程无限自旋。 现代互斥锁具有快速路径,在无竞争时效率惊人。 **指南:** * **<100ns,低竞争:** 自旋锁。自旋比上下文切换更快。 * **100ns-10μs,中等竞争:** 混合/自适应互斥锁(短暂自旋,然后休眠)。 * **>10μs 或高竞争:** 正常互斥锁。让调度器管理线程。 **性能分析是关键:** 使用 `perf stat` 监控上下文切换和缓存缺失,`strace -c` 统计系统调用次数,以及 `/proc/PID/status` 分析上下文切换类型。 最佳选择取决于您的特定临界区持续时间和竞争级别——测量,不要猜测!
## 30秒爱乐压计时器
这个项目源于制作爱乐压咖啡时计时不准确的困扰。为了避免依赖容易出错的手机计时器,制作者使用Adafruit Trinket M0(一个小型、兼容Arduino的板子)构建了一个专用的30秒计时器。
这个设备非常简单:一个按钮触发计时器,激活一个蜂鸣器,先发出一个短促的初始蜂鸣,然后在30秒后发出连续的鸣叫声。集成的Neopixel LED每秒闪烁一次,以视觉方式指示倒计时。该设计优先考虑功能而非精致,选择了一个3D打印的外壳(在Glowforge出现问题后),并使用USB连接供电——牺牲电池寿命以换取简洁性。
代码包括基本的去抖动、启动LED测试以及可调节的蜂鸣模式。虽然并非完美(计时可能略有偏差),但它是一个实用的解决方案,可以实现一致的爱乐压冲泡,即使在咖啡因起作用之前也能轻松使用。制作者有意跳过了电池供电和GitHub托管等功能,以保持它作为一个快速的周末项目。