You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GCC原子设置的内置函数是什么?是否需使用__sync_lock_test_and_set与__sync_lock_release配对?

关于GCC __sync_lock_test_and_set/__sync_lock_release的使用疑问解答

首先直接给结论:这对函数确实是实现自旋锁这类原子同步操作的标准用法,但并不是所有原子设置场景都必须依赖它们——具体得看你的实际需求。

这对函数的核心作用

  • __sync_lock_test_and_set(&lock, 1):这是一个原子操作,它会把lock变量的值原子地设置为1,同时返回lock原来的数值。你看到的示例里while (__sync_lock_test_and_set(&lock, 1));其实就是自旋等待逻辑:只要之前的锁状态是1(被其他线程持有),当前线程就不断尝试抢占,直到返回0(锁空闲,当前线程成功获取锁)。
  • __sync_lock_release(&lock):这个函数会原子地把lock设置为0,同时隐含了内存屏障,确保其他线程能立刻看到锁被释放的状态,避免因为CPU缓存或者指令重排导致的同步失效问题。

什么时候需要用这对函数?

如果你需要实现轻量级自旋锁(适合临界区执行时间极短的场景),这对函数是非常合适的选择——它们的设计初衷就是用来构建这类同步原语。

但如果你的需求只是单纯原子地设置一个变量的值(不需要等待锁的逻辑),那其实可以用更直接的函数,比如__sync_fetch_and_store(&var, new_val)(原子设置并返回旧值);甚至如果不需要返回旧值,__sync_lock_test_and_set也能完成,但有点大材小用。不过在GCC 4.1.0这个旧版本里,可选的原子函数不多,根据场景选择即可。

你提到的示例代码的合理性

那个自旋锁的示例是完全正确的典型实现:

volatile int lock = 0;
void *worker(void*) {
    while (__sync_lock_test_and_set(&lock, 1)); // 自旋等待获取锁
    // 临界区代码
    __sync_lock_release(&lock); // 释放锁
}

这里的volatile是个好习惯:虽然__sync_*系列函数本身会阻止编译器对变量读写做优化,但加上volatile能进一步确保变量的读写直接操作内存,避免极端情况下的编译器优化问题。

额外注意事项

  1. 自旋锁只适合临界区非常短的场景,如果临界区执行时间长,线程空等会浪费CPU资源,这时候用操作系统提供的互斥锁(比如pthread_mutex_t)更合适。
  2. GCC 4.1.0的__sync_*是比较老旧的原子接口,后续版本(4.7及以上)推出了更灵活的__atomic_*系列,支持不同的内存序控制,但如果你的环境只能用4.1.0,那__sync_*是唯一的内置原子操作选择。

内容的提问来源于stack exchange,提问作者S. Forman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:15:54