Ningx 中能够执行原子操作的原子变量只有整形,包括无符号整形 ngx_atomic_uint_t 和有符号整形 ngx_atomic_t ,这两种类型都使用了 volatile 关键字告诉 C 编译器不要做优化。
Nginx 支持的原子操作有如下两种:

  • ngx_atomic_cmp_set :比较并设置原子变量
  • ngx_atomic_fetch_add :增加原子变量的值并获取旧值

为了兼容不同架构,Nginx 对于上述两种原子操作封装了不同架构的实现,以下通过其中一种较为易读的方式分析

ngx_atomic_cmp_set

  • 首先比较原子变量 lockold 的值,如果相同则设置 lock 的值为 set,返回 1 表示设置成功
  • 对于其他架构的实现,有的使用了原子库有的使用了内联汇编
static ngx_inline ngx_atomic_uint_t
ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
    ngx_atomic_uint_t set)
{
    if (*lock == old) {
        *lock = set;
        return 1;
    }

    return 0;
}

ngx_atomic_fetch_add

  • value 中的值暂存到 old 中,value 的大小增加 add ,最后返回 old 的值
static ngx_inline ngx_atomic_int_t
ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add)
{
    ngx_atomic_int_t  old;

    old = *value;
    *value += add;

    return old;
}