Linux GCC 原子变量 实现互斥锁

背景

C语言的 结构化编程, 一般 对象的内存空间申请出来后, 初始化方式简单且粗暴, 一律清零操作.

如果对象的某属性需要串行访问 予以 保护.

用 pthread_mutex 互斥锁, 其初始化/析构 比较麻烦, 需要单独照顾.复杂的管理带来开发者的心智负担.

使用 原子操作可以达到 同样的功能, 且应用简单.
使用 原子操作可以达到 同样的功能, 且应用简单.
使用 原子操作可以达到 同样的功能, 且应用简单.

1
2
3
4
5
6
7
8
9
10
11
12
/*************** 内存管理器 ********************/
struct memoey_maneger_t{
int mutex;
int top;
int size;
void **space;
};
/*************** 内存管理器 ********************/

void *p = malloc(sizoef(struct memoey_maneger_t));
memset(p, 0, sizeof(struct memoey_maneger_t));
...

互斥锁需要解决的问题:

  1. 互斥,仅允许某个线程成功,其他线程不可以成功
  2. 被斥线程,不可以霸占地址总线,需要一种唤醒方式
  3. 被斥线程,唤醒后的竞争策略

GCC 原子操作

1
2
#define ATOMIC_FETCH_ADD(a)    __sync_fetch_and_add(a, 1) //先取值再运算
#define ATOMIC_FETCH_SUB(a) __sync_fetch_and_sub(a, 1) //先取值再运算

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
void user_lock(int *lock)
{
//互斥锁 -- 只有第一个才能通过, 其他人都陷入loop
while(ATOMIC_FETCH_ADD(lock))
{
usleep(1000 * ATOMIC_FETCH_SUB(lock)); //线程竞争 - 关键操作
}
}

void user_unlock(int *lock)
{
ATOMIC_FETCH_SUB(&flow->Alloc.mutex);
}

很好用