Gcc内置原子操作__sync_系列函数
Gcc内置原子操作__sync_系列函数简述及例程
Gcc 4.1.2版本之后,对X86或X86_64支持内置原子操作。就是说,不需要引入第三方库(如pthread)的锁保护,即可对1、2、4、8字节的数值或指针类型,进行原子加/减/与/或/异或等操作。
- __sync_fetch_and_add系列一共有十二个函数,有加/减/与/或/异或/等函数的原子性操作函
__snyc_fetch_and_add : 先fetch然后自加,返回的是自加以前的值
__snyc_add_and_fetch : 先自加然后返回,返回的是自加以后的值 (参照 ++i 和 i++)
__snyc_fetch_and_add的一个简单使用:
int count = 4;
__sync_fetch_and_add(&count, 1); // __sync_fetch_and_add(&count, 1) == 4
cout<<count<<endl; //--->count=5
2.对于多线程对全局变量进行自加,我们就再也不用理线程锁了。
下面这行代码,和上面被pthread_mutex保护的那行代码作用是一样的,而且也是线程安全的。
__sync_fetch_and_add( &global_int, 1 );
将__sync_系列17个函数声明整理简化如下:
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, ...);
__sync_fetch_and_add,速度是线程锁的6~7倍
type可以是1,2,4或者8字节长度的int类型,即:
int8_t
uint8_t
int16_t
uint16_t
int32_t
uint32_t
int64_t
uint64_t
3.例程
并编写了一个简单小例子,测试多个工作线程同时对同一个全局变量g_iSum进行加法操作时,使用__sync_fetch_and_add()原子操作进行原子加法,和不使用原子操作进行普通加法,观察它们运行结果的区别。每个工作线程加500万次,共10个工作线程,预期结果是5000万。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int g_iFlagAtom = 1;
#define WORK_SIZE 5000000
#define WORKER_COUNT 10
pthread_t g_tWorkId[WORKER_COUNT];
int g_iSum;
void* thr_work(void *arg)
{
printf("Work Thread %08X Startup\n", (unsigned int)pthread_self());
int i;
for(i = 0; i < WORK_SIZE; i++)
{
if(g_iFlagAtom)
__sync_fetch_and_add(&g_iSum, 1);
else
g_iSum++;
}
return NULL;
}
void* thr_management(void *arg)
{
printf("Management Thread %08X Startup\n", (unsigned int)pthread_self());
int i;
for(i = 0; i < WORKER_COUNT; i++)
{
pthread_join(g_tWorkId[i], NULL);
}
printf("All Work Thread Finished!\n");
return NULL;
}
int main(int argc, const char* argv[])
{
pthread_t tManagementId;
pthread_create(&tManagementId, NULL, thr_management, NULL);
int i;
for(i = 0; i < WORKER_COUNT; i++)
{
pthread_create(&g_tWorkId[i], NULL, thr_work, NULL);
}
printf("create %d worker threads\n", i);
pthread_join(tManagementId, NULL);
printf("the sum:%d\n", g_iSum);
return 0;
}
不使用原子操作
将g_iFlagAtom = 0,即不使用原子操作,可以看到输出结果无法达到预期的50000000,而且每次执行都可能得到不同的值。
gcc -Wall -o atom atom.cc -l pthread
./atom

使用原子操作
将g_iFlagAtom = 1,即使用原子操作,可以看到输出结果为预期的50000000,而且每次执行都得到这个值不变。
gcc -Wall -o atom1 atom.cc -l pthread
./atom1

Gcc内置原子操作__sync_系列函数的更多相关文章
- GCC内置函数
在C语言写的程序中,有时候没有包含头文件,直接调用一些函数,如printf,也不会报错,因为GCC内置和一些函数.如果包含了头文件,则去第三方库中链接这个函数,不再使用GCC内置的函数.每个编译器的内 ...
- gcc 内置函数
关于gcc内置函数和c隐式函数声明的认识以及一些推测 最近在看APUE,不愧是经典,看一点就收获一点.但是感觉有些东西还是没说清楚,需要自己动手验证一下,结果发现需要用gcc,就了解一下. 有时候 ...
- Python内置的字符串处理函数整理
Python内置的字符串处理函数整理 作者: 字体:[增加 减小] 类型:转载 时间:2013-01-29我要评论 Python内置的字符串处理函数整理,收集常用的Python 内置的各种字符串处理 ...
- 原子操作 Interlocked系列函数
上一篇<多线程第一次亲密接触 CreateThread与_beginthreadex本质区别>中讲到一个多线程报数功能.为了描述方便和代码简洁起见,我们可以只输出最后的报数结果来观察程序是 ...
- PHP内置的字符串处理函数
字符串的特点 1.其他类型的数据用在字符串类型处理函数中,会自动将其转化成字符串后,在处理 <?php echo substr("abcdefghijklmn",2,4 ...
- (转)原子操作 Interlocked系列函数
上一篇<多线程第一次亲密接触 CreateThread与_beginthreadex本质区别>中讲到一个多线程报数功能.为了描述方便和代码简洁起见,我们可以只输出最后的报数结果来观察程序是 ...
- 多线程面试题系列(3):原子操作 Interlocked系列函数
上一篇中讲到一个多线程报数功能.为了描述方便和代码简洁起见,我们可以只输出最后的报数结果来观察程序是否运行出错.这也非常类似于统计一个网站每天有多少用户登录,每个用户登录用一个线程模拟,线程运行时会将 ...
- thinkPHP内置字符串截取msubstr函数用法详解
作者:陈达辉 字体:[增加 减小] 类型:转载 时间:2016-11-15 我要评论 这篇文章主要介绍了thinkPHP内置字符串截取函数用法,结合实例形式分析了thinkPHP内置的字符串截取函数功 ...
- 秒杀多线程第三篇 原子操作 Interlocked系列函数
上一篇<多线程第一次亲密接触 CreateThread与_beginthreadex本质区别>中讲到一个多线程报数功能.为了描述方便和代码简洁起见,我们可以只输出最后的报数结果来观察程序是 ...
- python内置常用高阶函数(列出了5个常用的)
原文使用的是python2,现修改为python3,全部都实际输出过,可以运行. 引用自:http://www.cnblogs.com/duyaya/p/8562898.html https://bl ...
随机推荐
- 排序:使数组唯一的最小增量 (3.22 leetcode每日打卡)
给定整数数组 A,每次 move 操作将会选择任意 A[i],并将其递增 1. 返回使 A 中的每个值都是唯一的最少操作次数. 示例 1: 输入:[1,2,2]输出:1解释:经过一次 move 操作, ...
- C语言求s=1+(1+2)+…+(1+2+3+…+n)的值,其中n由键盘输入。
#include<stdio.h> void main() { int n, s=0; scanf_s("%d", &n); for (n; n > 0; ...
- 基于FFmpeg和Qt实现简易视频播放器
VideoPlay001 记得一键三连哦 使用qt+ffmpeg开发简单的视频播放器,无声音 视频解码使用的是软解码即只用CPU进行QPainter绘制每一帧图像,CPU占用过高 简单易学,适合小白入 ...
- Netty源码学习7——netty是如何发送数据的
零丶引入 系列文章目录和关于我 经过<Netty源码学习4--服务端是处理新连接的&netty的reactor模式和<Netty源码学习5--服务端是如何读取数据的>,我们了 ...
- Guava Preconditions类的各种用法
公众号「架构成长指南」,专注于生产实践.云原生.分布式系统.大数据技术分享. Guava Preconditions类 提供静态方法列表,用于检查是否使用有效参数值调用方法或构造函数.如果前提条件失败 ...
- AtCoder_abc331
AtCoder_abc331 (这次题真的真的真的好难) 比赛链接 A - Tomorrow 题目链接 题目大意 有一个\(M\)个月,\(D\)天的日历,请输出\(y年m月z日\)的下一天. 解题思 ...
- ElasticSearch索引生命周期策略配置(ES TTL)
背景 有些索引数据作为临时数据存放,一段时间后我们希望索引可以自动过期删除,就是常说的TTL(Time To Live)机制 ElasticSearch索引数量过多会占用很多主分片和副本分片,最终导致 ...
- CISC与RISC
- 解决/usr/bin/pip: No such file or directory
问题描述: 因为home的空间不足,所以我将anaconda3文件夹移动到了别的位置上了,导致我在命令行中输入python的命令时,显示的是python2.7(也就是linux自带的),后面我又为an ...
- Pikachu漏洞靶场 Burte Force(暴力破解)
Burte Force(暴力破解) 文章目录 Burte Force(暴力破解) 概述 1.基于表单的暴力破解 2.验证码绕过(on server) 3.验证码绕过(on client) 4.toke ...