热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

以下代码loop出自NGINX,稍微修改的。atomic_lock.h1#pragmaonce2#ifndef_atomic_lock_h_include_3#define_a

以下代码loop出自NGINX,稍微修改的。


"atomic_lock.h"
 1 #pragma once
2 #ifndef _atomic_lock_h_include_
3 #define _atomic_lock_h_include_
4
5 #define spin_num (2048)
6
7 #ifdef _MSC_VER
8
9 #include
10
11 #define cpu_pause() _mm_pause()
12 #define thread_yield() SwitchToThread()
13
14 __forceinline int compare_and_swap(long volatile *des, long out, long set)
15 {
16 InterlockedCompareExchange(des, set, out);
17 return *des == set;
18 }
19
20 #endif
21
22 #ifdef __GNUC__
23
24 #include
25
26 #define cpu_pause() __asm__ ("pause")
27 #define thread_yield() sched_yield()
28
29 #if defined(__INTEL_COMPILER) || (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1))
30 #define USE_BUILTINS
31 #endif
32
33 static inline int compare_and_swap(volatile long* x, long oldval, long newval) {
34 #ifdef USE_BUILTINS
35 return __sync_bool_compare_and_swap(x, oldval, newval);
36 #elif defined(__i386__)
37 char result;
38 asm volatile ("lock; cmpxchgl %3, %0; setz %1" : "=m"(*x), "=q" (result) : "m" (*x), "r" (newval), "a" (oldval) : "memory");
39 return result;
40 #elif defined(__x86_64__)
41 char result;
42 asm volatile ("lock; cmpxchgq %3, %0; setz %1" : "=m"(*x), "=q" (result) : "m" (*x), "r" (newval), "a" (oldval) : "memory");
43 return result;
44 #else
45 #error architecture not supported and gcc too old.
46 #endif
47 }
48
49 #endif
50
51 typedef struct {
52 volatile long lock;
53 } app_atomic_lock_t;
54
55
56 int app_atomic_trylock(app_atomic_lock_t* lt, long value);
57
58 void app_atomic_lock(app_atomic_lock_t* lt, long value);
59
60 void app_atomic_unlock(app_atomic_lock_t* lt, long value);
61 #endif

"atomic_lock.c"
 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(<->lock, 0, value)); 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(<->lock, 0, value)) {
17 return;
18 }
19 for (n = 1; n 1) {
20
21 for (i = 0; i ) {
22 cpu_pause();
23 }
24
25 if (lt->lock == 0 && compare_and_swap(<->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 compare_and_swap(<->lock, value, 0);
37 }

 

#include "atomic_lock.h"

app_atomic_lock_t
lock;
volatile int value;

void* th_fun(void *arg)
{
int i;
for (i = 0; i <10000; i++){

app_atomic_lock(
&lock, 100);
value
++;
app_atomic_unlock(
&lock, 100);
}
return NULL;
}

int main()
{
lock.lock = 0;

pthread_t th1, th2;

pthread_create(
&th1, NULL, th_fun, NULL);
pthread_create(
&th2, NULL, th_fun, NULL);

pthread_join(th1, NULL);
pthread_join(th2, NULL);

printf(
"%d\n", value);
return 0;
}

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

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


                        
                        
                         
推荐阅读
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 31.项目部署
    目录1一些概念1.1项目部署1.2WSGI1.3uWSGI1.4Nginx2安装环境与迁移项目2.1项目内容2.2项目配置2.2.1DEBUG2.2.2STAT ... [详细]
  • 本文概述了JNI的原理以及常用方法。JNI提供了一种Java字节码调用C/C++的解决方案,但引用类型不能直接在Native层使用,需要进行类型转化。多维数组(包括二维数组)都是引用类型,需要使用jobjectArray类型来存取其值。此外,由于Java支持函数重载,根据函数名无法找到对应的JNI函数,因此介绍了JNI函数签名信息的解决方案。 ... [详细]
  • 本文介绍了关于Java异常的八大常见问题,包括异常管理的最佳做法、在try块中定义的变量不能用于catch或finally的原因以及为什么Double.parseDouble(null)和Integer.parseInt(null)会抛出不同的异常。同时指出这些问题是由于不同的开发人员开发所导致的,不值得过多思考。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了源码分析--ConcurrentHashMap与HashTable(JDK1.8)相关的知识,希望对你有一定的参考价值。  Concu ... [详细]
  • 原文地址http://balau82.wordpress.com/2010/02/28/hello-world-for-bare-metal-arm-using-qemu/最开始时 ... [详细]
  • ZABBIX 3.0 配置监控NGINX性能【OK】
    1.在agent端查看配置:nginx-V查看编辑时是否加入状态监控模块:--with-http_stub_status_module--with-http_gzip_stat ... [详细]
  • 学习笔记17:Opencv处理调整图片亮度和对比度
    一、理论基础在数学中我们学过线性理论,在图像亮度和对比度调节中同样适用,看下面这个公式:在图像像素中其中:参数f(x)表示源图像像素。参数g(x)表示输出图像像素。 ... [详细]
  • centos6.8 下nginx1.10 安装 ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了VoLTE端到端业务详解|VoLTE用户注册流程相关的知识,希望对你有一定的参考价值。书籍来源:艾怀丽 ... [详细]
  • 【技术分享】一个 ELF 蠕虫分析
    【技术分享】一个 ELF 蠕虫分析 ... [详细]
  • golang源码分析调度概述
    golang源码分析-调度过程概述本文主要概述一下golang的调度器的大概工作的流程,众所周知golang是基于用户态的协程的调度来完成多任务的执行。在Linux ... [详细]
  • 32位ubuntu编译android studio,32位Ubuntu编译Android 4.0.4问题
    问题一:在32位Ubuntu12.04上编译Android4.0.4源码时,出现了关于emulator的错误,关键是其Makefile里的 ... [详细]
  • 第七章•Firewalld防火墙实战
    1、防火墙安全基本概述在CentOS7系统中集成了多款防火墙管理工具,默认启用的是firewalld(动态防火墙管理器)防火墙管理工具,Firewalld支持CLI(命令行)以及G ... [详细]
author-avatar
54打工仔i_858
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有