首页 > 代码库 > 使用CAS实现高效并发处理
使用CAS实现高效并发处理
在并发处理应用中,一般使用锁的方式来解决竞争问题,但锁的效率比较低,因此,在高并发处理中,无锁队列成为应用的需要。CAS无锁算法主要依赖于处理器的支持,绝大多数处理器都支持:
X86平台:CMPXCHG 汇编指令。
API函数GCC4.1
Linux内核中实现方法:
应用代码
无锁队列的具体应用示例
以下是作者在某NOSQL数据库中针对高并发情况使用无锁队列的应用示例。
X86平台:CMPXCHG 汇编指令。
在一个指令周期内执行完成,因此是原子性的。
这一原理性操作过程如果采用C描述如下:
intcompare_and_swap (int* reg, int oldval, int newval)
{
int old_reg_val = *reg;
if (old_reg_val == oldval)
*reg = newval;
return old_reg_val;
}
boolcompare_and_swap (int *accum, int *dest, int newval)
{
if ( *accum == *dest ) {
*dest = newval;
return true;
}
return false;
}
API函数GCC4.1
bool__sync_bool_compare_and_swap (type *ptr, type oldval, type newval, ...)
type__sync_val_compare_and_swap (type *ptr, type oldval, type newval, ...)
Linux内核中实现方法:
ARM实现版本
staticinline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
{
unsigned long oldval, res;
smp_mb();/*内存屏障*/
do {
__asm__ __volatile__("@atomic_cmpxchg\n"
"ldrex %1, [%2]\n"
"mov %0, #0\n"
"teq %1, %3\n"
"strexeq %0, %4, [%2]\n"
: "=&r" (res), "=&r" (oldval)
: "r" (&ptr->counter), "Ir" (old),"r" (new)
: "cc");
} while (res);
smp_mb();
return oldval;
}
X86版本
staticinline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
unsigned long new, int size)
{
unsigned long prev;
switch (size) {
case 1:
asm volatile(LOCK_PREFIX"cmpxchgb %b2,%1"
: "=a"(prev),"+m"(*__xg(ptr))
: "q"(new), "0"(old)
: "memory");
return prev;
case 2:
asm volatile(LOCK_PREFIX"cmpxchgw %w2,%1"
: "=a"(prev),"+m"(*__xg(ptr))
: "r"(new), "0"(old)
: "memory");
return prev;
case 4:
asm volatile(LOCK_PREFIX"cmpxchgl %2,%1"
: "=a"(prev),"+m"(*__xg(ptr))
: "r"(new), "0"(old)
: "memory");
return prev;
}
return old;
}
应用代码
无锁队列的具体应用示例
以下是作者在某NOSQL数据库中针对高并发情况使用无锁队列的应用示例。
typedefstruct _pool
{
……
node_object *pool_link_head;
node_object *pool_link_tail;
}pool;
获取结点
do
{
ptr = pool->pool_link_head;
if(ptr->next == NULL)
{
DERROR("pool empty,but norealloc.exit.....\n");
KDB_EXIT;
}
}while(B_CAS(&(pool->pool_link_head), ptr , ptr->next) !=TRUE);
pool->free_count++; /*this is not thread safe, may use atomic_t */
return ptr;
释放结点:
1 do{
2 ptr = pool->pool_link_tail;
3 }while(B_CAS(&(ptr->next),NULL,temp)!= TRUE );
4
5 pool->free_count++; /*during this critical area ,no other thread can modify thepool ds*/
6
7 B_CAS(&(pool->pool_link_tail),oldtail , temp);
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。