__sync_fetch_and_add系列
__sync_fetch_and_add系列一共有十二个函数,有加/减/与/或/异或/等函数的原子性操作函数,__sync_fetch_and_add,顾名思义,先fetch,然后自加,返回的是自加以前的值。以count = 4为例,调用__sync_fetch_and_add(&count,1),之后,返回值是4,然后,count变成了5.
有__sync_fetch_and_add,自然也就有__sync_add_and_fetch,呵呵这个的意思就很清楚了,先自加,在返回。他们哥俩的关系与i++和++i的关系是一样的。被谭浩强他老人家收过保护费的都会清楚了。
有了这个宝贝函数,我们就有新的解决办法了。对于多线程对全局变量进行自加,我们就再也不用理线程锁了。下面这行代码,和上面被pthread_mutex保护的那行代码作用是一样的,而且也是线程安全的。
__sync_fetch_and_add( &global_int, 1 );
下面是这群函数的全家福,大家看名字就知道是这些函数是干啥的了。
type __sync_fetch_and_add (type *ptr, type value);
type __sync_fetch_and_sub (type *ptr, type value);
type __sync_fetch_and_or (type *ptr, type value);
type __sync_fetch_and_and (type *ptr, type value);
type __sync_fetch_and_xor (type *ptr, type value);
type __sync_fetch_and_nand (type *ptr, type value);
type __sync_add_and_fetch (type *ptr, type value);
type __sync_sub_and_fetch (type *ptr, type value);
type __sync_or_and_fetch (type *ptr, type value);
type __sync_and_and_fetch (type *ptr, type value);
type __sync_xor_and_fetch (type *ptr, type value);
type __sync_nand_and_fetch (type *ptr, type value);
这些都是c++11以后支持的。
其他:
bool __sync_bool_compare_and_swap (type *ptr, type oldval type newval, ...)
type __sync_val_compare_and_swap (type *ptr, type oldval type newval, ...) 这两个函数提供原子的比较和交换,如果*ptr == oldval,就将newval写入*ptr,
第一个函数在相等并写入的情况下返回true.
第二个函数在返回操作之前的值。 __sync_synchronize (...)
发出一个full barrier. 关于memory barrier,cpu会对我们的指令进行排序,一般说来会提高程序的效率,但有时候可能造成我们不希望得到的结果,举一个例子,比如我们有一个硬件设备,它有4个寄存器,当你发出一个操作指令的时候,一个寄存器存的是你的操作指令(比如READ),两个寄存器存的是参数(比如是地址和size),最后一个寄存器是控制寄存器,在所有的参数都设置好之后向其发出指令,设备开始读取参数,执行命令,程序可能如下: write1(dev.register_size,size);
write1(dev.register_addr,addr);
write1(dev.register_cmd,READ);
write1(dev.register_control,GO);
如果最后一条write1被换到了前几条语句之前,那么肯定不是我们所期望的,这时候我们可以在最后一条语句之前加入一个memory barrier,强制cpu执行完前面的写入以后再执行最后一条: write1(dev.register_size,size);
write1(dev.register_addr,addr);
write1(dev.register_cmd,READ);
__sync_synchronize();
write1(dev.register_control,GO); memory barrier有几种类型:
acquire barrier : 不允许将barrier之后的内存读取指令移到barrier之前(linux kernel中的wmb())。
release barrier : 不允许将barrier之前的内存读取指令移到barrier之后 (linux kernel中的rmb())。
full barrier : 以上两种barrier的合集(linux kernel中的mb())。 还有两个函数: type __sync_lock_test_and_set (type *ptr, type value, ...)
将*ptr设为value并返回*ptr操作之前的值。 void __sync_lock_release (type *ptr, ...)
将*ptr置0
__sync_fetch_and_add系列的更多相关文章
- linux无锁化编程--__sync_fetch_and_add系列原子操作函数
linux支持的哪些操作是具有原子特性的?知道这些东西是理解和设计无锁化编程算法的基础. 下面的东西整理自网络.先感谢大家的分享! __sync_fetch_and_add系列的命令,发现这个系列命令 ...
- [充电]多线程无锁编程--原子计数操作:__sync_fetch_and_add等12个操作
转自:http://blog.csdn.net/minCrazy/article/details/40791795 多线程间计数操作.共享状态或者统计相关时间次数,这些都需要在多线程之间共享变量和修改 ...
- __sync_fetch_and_add
最近在公司离职的前辈写的代码哪里看到了__sync_fetch_and_add这个东东.比较好奇.找些资料学习学习 http://www.lxway.com/4091061956.htm http:/ ...
- [转] 多线程下变量-gcc原子操作 __sync_fetch_and_add等
http://blog.sina.com.cn/s/blog_6f5b220601013zw3.html 非常好的原子操作,不用加锁:__sync_fetch_and_add GCC 提供的原子操作 ...
- __sync_fetch_and_add函数(Redis源码学习)
__sync_fetch_and_add函数(Redis源码学习) 在学习redis-3.0源码中的sds文件时,看到里面有如下的C代码,之前从未接触过,所以为了全面学习redis源码,追根溯源,学习 ...
- Linux下的原子操作
linux支持的哪些操作是具有原子特性的?知道这些东西是理解和设计无锁化编程算法的基础. __sync_fetch_and_add系列的命令,发现这个系列命令讲的最好的一篇文章,英文好的同学可以直接去 ...
- C语言常见的函数调用
C语言常见的函数调用 isatty,函数名,主要功能是检查设备类型,判断文件描述词是否为终端机. 函数名: isatty 用 法: int isatty(int desc); 返回值:如果参数desc ...
- Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求
上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...
- 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新
本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...
随机推荐
- 机器学习算法实现解析——libFM之libFM的训练过程概述
本节主要介绍的是libFM源码分析的第四部分--libFM的训练. FM模型的训练是FM模型的核心的部分. 4.1.libFM中训练过程的实现 在FM模型的训练过程中,libFM源码中共提供了四种训练 ...
- Redis设计与实现 (三): 字典
哈希表 结构定义dict.h/dictht /* * 哈希表 * * 每个字典都使用两个哈希表,从而实现渐进式 rehash . */ typedef struct dictht { // 哈希表数 ...
- 转载 关于case语句的优先级
对于这样的组合逻辑电路 always@(X) case(X) X1: X2: …… endcase 如果分支项包含变量X的所有取值情况,并且互相不重复,那么这样的情况,其实没有必要使用综合指令. (一 ...
- 十二、python沉淀之路--内置函数
1.abs函数,求绝对值. a = abs(-3) print(a) 返回:3 2.all函数:判断是否是可迭代对象. 官方解释:Return True if bool(x) is True for ...
- bzoj 3277 & bzoj 3473,bzoj 2780 —— 广义后缀自动机
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3277 https://www.lydsy.com/JudgeOnline/problem.p ...
- 转JMeter 利用Jmeter批量数据库插入数据
1. 启动Jmeter 2. 添加 DBC Connection Configuration 右键线程组->添加->配置元件->JDBC Connection Configu ...
- Jave 文件介绍
Java程序的基本组成单元是类,有class声明,类体中包括属性和方法. 一个Java文件中可以有多个class声明,但由public修饰的类只能有一个,并且类名作为该文件的名称. 每一个应用程序都必 ...
- 发现一个github的奇葩设定
commit时留下的邮箱,会显示在github的提交记录里,然后居然自动找服务器上的这个邮箱注册的人,显示这个用户名.
- 利用ffmpeg一步一步编程实现摄像头采集编码推流直播系统
了解过ffmpeg的人都知道,利用ffmpeg命令即可实现将电脑中摄像头的画面发布出去,例如发布为UDP,RTP,RTMP等,甚至可以发布为HLS,将m3u8文件和视频ts片段保存至Web服务器,普通 ...
- 1024 Palindromic Number
题意: 给出一个数N(N<=10^10),最多可操作K次(K<=100),每次操作为这个数和其反转之后的数相加,若得到的结果为回文数,则输出:若在K次迭代后仍然不是回文数,在输出第K次操作 ...