CAS原子锁 高效自旋无锁的正确用法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CAS原子锁 高效自旋无锁的正确用法相关的知识,希望对你有一定的参考价值。

 1 #pragma once
 2 #ifndef _atomic_lock_h_include_
 3 #define _atomic_lock_h_include_
 4 
 5 #include <windows.h>
 6 
 7 #define cpu_pause()  __asm {pause}
 8 #define thread_yield()         Yield()
 9 
10 #define spin_num (2048)
11 
12 typedef struct {
13     volatile long   lock;
14 } app_atomic_lock_t;
15 
16 __forceinline int compare_and_swap(long volatile *des, long out, long set)
17 {
18     InterlockedCompareExchange(des, set, out);
19     return *des == set;
20 }
21 
22 int app_atomic_trylock(app_atomic_lock_t* lt, long value);
23 
24 void app_atomic_lock(app_atomic_lock_t* lt, long value);
25 
26 void app_atomic_unlock(app_atomic_lock_t* lt, long value);
27 #endif

 

 1 #include "atomic_lock.h"
 2 
 3 int app_atomic_trylock(app_atomic_lock_t * lt, long value)
 4 {
 5     return (lt->lock == 0 &&
 6          compare_and_swap(&lt->lock, 0, value));
 7     return 0;
 8 }
 9 
10 void app_atomic_lock(app_atomic_lock_t * lt, long value)
11 {
12     u_int n, i;
13 
14     for (;; ) {
15         
16         if (lt->lock == 0 && compare_and_swap(&lt->lock, 0, value)) {
17             return;
18         }
19         for (n = 1; n < spin_num; n <<= 1) {
20 
21             for (i = 0; i < n; i++) {
22                 cpu_pause();
23             }
24 
25             if (lt->lock == 0 && compare_and_swap(&lt->lock, 0, value)) {
26                 return;
27             }
28         }
29 
30         thread_yield();
31     }
32 }
33 
34 void app_atomic_unlock(app_atomic_lock_t * lt, long value)
35 {
36     return compare_and_swap(&lt->lock, value, 0);
37 }

 

cas在loop抢占的时候,会大量消耗cpu,在x86指令集下,可以用pause指令来减少loop的消耗。

cas锁在极高并发时候,会有非常大的帮助,相反,并发不高或者抢占时间过长,则千万不要用cas无锁。

以上代码只能在x86下编译,x64不能通过,需要重写pause指令实现。

以上是关于CAS原子锁 高效自旋无锁的正确用法的主要内容,如果未能解决你的问题,请参考以下文章

CAS原子操作实现无锁及性能分析

无锁自旋锁偏向锁轻量级锁和重量级锁

CAS 自旋锁

锁——待优化

深入理解CAS (自旋锁)

Java中的自旋锁,手动实现一个自旋锁