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

多线程(12)atomic原子操作系列接口

多线程(12)atomic原子操作系列接口1.原子操作1.1atomic_t源码定义2.使用场景3.接口4.例子5.扩展:atomic_a

多线程(12)atomic 原子操作系列接口

  • 1. 原子操作
    • 1.1 atomic_t 源码定义
  • 2. 使用场景
  • 3. 接口
  • 4. 例子
  • 5. 扩展:atomic_add_unless
  • 参考


1. 原子操作

所谓原子操作,就是该操作绝不会在执行完毕前被任何其他任务或事件打断。也就说,它是最小的执行单位,不可能有比它更小的执行单位,因此这里的原子实际是使用了物理学里的物质微粒的概念。
  总结就是: 不可中断的操作。

1.1 atomic_t 源码定义

linux专门定义了一种只进行原子操作的类型atomic_t

typedef struct { volatile int counter;
} atomic_t;

原子变量作用:
主要是防止读取的是寄存器的内容,而内存的值已经被其他线程改变,主要是因为多线程的原因

本质: 原子类型其实是int类型,只是禁止寄存器对其暂存。

volatile 关键字
https://mp.csdn.net/mp_blog/creation/success/105363581

2. 使用场景

原子操作主要用于实现资源计数
很多引用计数(refcnt)就是通过原子操作实现的。

3. 接口

atomic_read(atomic_t * v); //原子读操作,它返回原子类型的变量v的值
atomic_set(atomic_t * v, int i);//设置原子类型的变量v的值为i
void atomic_add(int i, atomic_t *v); //给原子类型的变量v增加值i
atomic_sub(int i, atomic_t *v); //从原子类型的变量v中减去i。
int atomic_sub_and_test(int i, atomic_t *v); //从原子类型的变量v中减去i,并判断结果是否为0,如果为0,返回真,否则返回假。
void atomic_inc(atomic_t *v); //对原子类型变量v原子地增加1。
void atomic_dec(atomic_t *v); //对原子类型的变量v原子地减1。
int atomic_add_negative(int i, atomic_t *v);//对原子类型的变量v原子地增加I,并判断结果是否为负数,如果是,返回真,否则返回假。
int atomic_add_return(int i, atomic_t *v);//对原子类型的变量v原子地增加i,并且返回指向v的指针。
int atomic_sub_return(int i, atomic_t *v);//从原子类型的变量v中减去i,并且返回指向v的指针。
int atomic_inc_return(atomic_t * v);//对原子类型的变量v原子地增加1并且返回指向v的指针。
int atomic_dec_return(atomic_t * v);//对原子类型的变量v原子地减1并且返回指向v的指针。

4. 例子

atomic_t stCount;
atomic_set(&(stCount), 0); /* 初始化 */
atomic_inc(&(stCount));/* 累加 */
unsigned int iRet = (unsigned int)atomic_read(&(stCount)); /* 读取 */

5. 扩展:atomic_add_unless

int atomic_add_unless(atomic_t *v, int a, int u)

功能:

如果 v!=u 则 v+=a 返回非0 如果 v=u 则 不处理v 返回0

参数说明

v:原子类型变量指针。关于原子类型atomic_t的定义参考atomic_set()函数的分析。a:整型值,在v的值不为u时,原子类型变量的值将在其原有基础上增加该变量值。u:整型值,被用来与v的值进行比较来决定是否对v进行增加a。

返回值:

返回一个整型值,如果起初原子类型v的值即与u相等,则返回0,否则返回非0值。

例子:

(VOID)atomic_add_unless(&pstStatHashNode->stActiveConnections, -1, 0);
就是 stActiveConnections-1

源码实现:

static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
{ int ret; unsigned long flags; raw_local_irq_save(flags); ret = v->counter; if (likely(ret == old)) v->counter = new; raw_local_irq_restore(flags); return ret;
}static inline int atomic_add_unless(atomic_t *v, int a, int u)
{ int c, old; c = atomic_read(v); while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c) c = old; return c != u;
}

参考

https://www.cnblogs.com/still-smile/p/11652788.html
https://www.cnblogs.com/wanghuaijun/p/7705045.html


推荐阅读
  • 本文介绍了 Go 语言中的高性能、可扩展、轻量级 Web 框架 Echo。Echo 框架简单易用,仅需几行代码即可启动一个高性能 HTTP 服务。 ... [详细]
  • C#实现文件的压缩与解压
    2019独角兽企业重金招聘Python工程师标准一、准备工作1、下载ICSharpCode.SharpZipLib.dll文件2、项目中引用这个dll二、文件压缩与解压共用类 ... [详细]
  • 本文是Java并发编程系列的开篇之作,将详细解析Java 1.5及以上版本中提供的并发工具。文章假设读者已经具备同步和易失性关键字的基本知识,重点介绍信号量机制的内部工作原理及其在实际开发中的应用。 ... [详细]
  • QT框架中事件循环机制及事件分发类详解
    在QT框架中,QCoreApplication类作为事件循环的核心组件,为应用程序提供了基础的事件处理机制。该类继承自QObject,负责管理和调度各种事件,确保程序能够响应用户操作和其他系统事件。通过事件循环,QCoreApplication实现了高效的事件分发和处理,使得应用程序能够保持流畅的运行状态。此外,QCoreApplication还提供了多种方法和信号槽机制,方便开发者进行事件的定制和扩展。 ... [详细]
  • Java 中的等时日期(int,int)方法,示例 ... [详细]
  • WCF类型共享的最佳实践
    在使用WCF服务时,经常会遇到同一个实体类型在不同服务中被生成为不同版本的问题。本文将介绍几种有效的类型共享方法,以解决这一常见问题。 ... [详细]
  • 2020年9月15日,Oracle正式发布了最新的JDK 15版本。本次更新带来了许多新特性,包括隐藏类、EdDSA签名算法、模式匹配、记录类、封闭类和文本块等。 ... [详细]
  • 本文总结了Java初学者需要掌握的六大核心知识点,帮助你更好地理解和应用Java编程。无论你是刚刚入门还是希望巩固基础,这些知识点都是必不可少的。 ... [详细]
  • 浅析python实现布隆过滤器及Redis中的缓存穿透原理_python
    本文带你了解了位图的实现,布隆过滤器的原理及Python中的使用,以及布隆过滤器如何应对Redis中的缓存穿透,相信你对布隆过滤 ... [详细]
  • JUC(三):深入解析AQS
    本文详细介绍了Java并发工具包中的核心类AQS(AbstractQueuedSynchronizer),包括其基本概念、数据结构、源码分析及核心方法的实现。 ... [详细]
  • 本文介绍了几种常用的图像相似度对比方法,包括直方图方法、图像模板匹配、PSNR峰值信噪比、SSIM结构相似性和感知哈希算法。每种方法都有其优缺点,适用于不同的应用场景。 ... [详细]
  • 本文介绍了UUID(通用唯一标识符)的概念及其在JavaScript中生成Java兼容UUID的代码实现与优化技巧。UUID是一个128位的唯一标识符,广泛应用于分布式系统中以确保唯一性。文章详细探讨了如何利用JavaScript生成符合Java标准的UUID,并提供了多种优化方法,以提高生成效率和兼容性。 ... [详细]
  • 本文详细介绍了Oracle数据库中的表空间及其分区技术。表空间作为Oracle数据库的一个逻辑单元,每个数据库可包含一个或多个表空间,每个表空间则关联一个或多个数据文件。通过合理的表空间管理和分区策略,可以显著提升数据库的性能和管理效率。文章还总结了实际应用中的最佳实践,为读者提供了宝贵的参考。 ... [详细]
  • React项目基础教程第五课:深入解析组件间通信机制 ... [详细]
  • HBase Java API 进阶:过滤器详解与应用实例
    本文详细探讨了HBase 1.2.6版本中Java API的高级应用,重点介绍了过滤器的使用方法和实际案例。首先,文章对几种常见的HBase过滤器进行了概述,包括列前缀过滤器(ColumnPrefixFilter)和时间戳过滤器(TimestampsFilter)。此外,还详细讲解了分页过滤器(PageFilter)的实现原理及其在大数据查询中的应用场景。通过具体的代码示例,读者可以更好地理解和掌握这些过滤器的使用技巧,从而提高数据处理的效率和灵活性。 ... [详细]
author-avatar
跟-着感觉走
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有