使用gcc内置CAS函数实现spinlock

本文介绍了GCC中内置的原子比较并交换(CAS)函数__atomic_compare_exchange_n(),用于实现并发控制。通过示例展示了如何使用CAS函数创建spinlock,保证多线程环境下对共享资源的互斥访问。代码展示了如何在多线程程序中利用CAS进行同步,并最终达到无锁编程的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        gcc 里提供了内置 CAS 函数:__atomic_compare_exchange_n(),它的基本用法如下:

Built-in Function: bool __atomic_compare_exchange_n (type *ptr, type *expected, type desired, bool weak, int success_memorder, int failure_memorder)

This built-in function implements an atomic compare and exchange operation. This compares the contents of *ptr with the contents of *expected. If equal, the operation is a read-modify-write operation that writes desired into *ptr. If they are not equal, the operation is a read and the current contents of *ptr are written into *expected. weak is true for weak compare_exchange, which may fail spuriously, and false for the strong variation, which never fails spuriously. Many targets only offer the strong variation and ignore the parameter. When in doubt, use the strong variation.

If desired is written into *ptr then true is returned and memory is affected according to the memory order specified by success_memorder. There are no restrictions on what memory order can be used here.

Otherwise, false is returned and memory is affected according to failure_memorder. This memory order cannot be __ATOMIC_RELEASE nor __ATOMIC_ACQ_REL. It also cannot be a stronger order than that specified by success_memorder.

        在使用中,可以用它来实现 spinlock,具体代码如下:

#include <stdio.h>
#include <stdbool.h>
#include <pthread.h>

#define THREAD_NUM 32 

volatile unsigned int sum = 0;
unsigned int max = 10000000; 
volatile bool cond = true;

typedef int slock_t;

static __inline__ int
cas(volatile slock_t *lock)
{
        slock_t expected = 0;
        return !(__atomic_compare_exchange_n(lock, &expected, (slock_t)1,
                                false, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE));
}

#define S_UNLOCK(lock) __atomic_store_n(lock, (slock_t)0, __ATOMIC_RELEASE)
#define S_INIT_LOCK(lock)       S_UNLOCK(lock)
#define SPIN(lock)    (*(lock) ? 1 : cas(lock))

volatile slock_t g_lock;

int s_lock(volatile slock_t *lock)
{
	int i = 0;

	while (SPIN(lock))
	{
		++i;
	}

	return i; 
}

void *thread_func(void *args)
{
	while ((cond = sum < max)) {
		s_lock(&g_lock);
		++sum;
		S_UNLOCK(&g_lock);
	}
	
	return NULL;
}

int main(void)
{
	pthread_t pids[THREAD_NUM];
	int i, ret;
	void *val;
	double start, end;

	S_INIT_LOCK(&g_lock);

	for (i = 0; i < THREAD_NUM; ++i) {
		ret = pthread_create(&pids[i], NULL, thread_func, NULL); 
	}

	for (i = 0; i < THREAD_NUM; ++i) {
		pthread_join(pids[i], &val);
	}

	printf("final sum: %d\n", sum);

	return 0;
}

        运行结果如下:

$ ./main 
final sum: 10000031

参考资料

1. https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值