如何使用AtomicExchange实现TDirection枚举变量的跨平台线程安全访问?
线程安全实现方案
1. 原子操作适配改造
你的枚举默认是小字节类型,为了适配全平台原子操作的兼容性,先显式指定枚举的底层存储为32位整型,避免部分平台对非32位/64位变量的原子操作兼容性问题:
type // 显式指定底层为32位整型,保证全平台原子操作支持 TDirection = type Integer(lessThan, GreaterThan); var MyDirection: TDirection;
基础操作实现
所有原子操作都可以直接用Delphi标准库内置的跨平台原子函数(位于System.Atomic单元,XE7及以上版本原生支持全平台):
- 读取变量:
function GetDirection: TDirection; begin // AtomicLoad自带内存屏障,保证弱内存序平台(ARM/Android/iOS)也能拿到最新值 Result := TDirection(AtomicLoad(MyDirection)); end;
- 直接赋值修改变量:
procedure SetDirection(NewDir: TDirection); begin AtomicExchange(MyDirection, Integer(NewDir)); end;
- 条件修改(仅当前值等于预期值时才修改):
// 返回值为修改前的旧值,和预期值相等说明修改成功 function TryChangeDirection(ExpectDir, NewDir: TDirection): Boolean; var OldVal: Integer; begin OldVal := AtomicCmpExchange(MyDirection, Integer(NewDir), Integer(ExpectDir)); Result := (OldVal = Integer(ExpectDir)); end;
这个方案的开销只有几纳秒,比任何锁方案快10~100倍,完全满足性能要求,原生兼容Win32/Win64/macOS/Android/iOS所有平台。
2. 其他可选跨平台高性能方案
如果后续业务场景扩展,需要保护更复杂的操作,可以选择以下方案:
- 轻量临界区:Delphi自带的
TCriticalSection比TMonitor轻量非常多,无竞争时开销仅十几纳秒,适合需要保护的逻辑在几微秒内完成的场景,全平台兼容。 - 自旋锁:如果需要保护的代码段执行时间极短(小于1微秒),可以用基于
AtomicCmpExchange实现的用户态自旋锁,没有内核态切换开销,比临界区更快。 - 序列锁(SeqLock):如果是读多写极少的场景,序列锁可以做到读操作完全无锁,开销和普通变量读几乎一致,写操作也不需要阻塞读端,适合高频读取的场景。
内容的提问来源于stack exchange,提问作者zeus
相关产品推荐
相关产品推荐

