博客
关于我
Linux内核同步机制之(一):原子操作
阅读量:142 次
发布时间:2019-02-26

本文共 1019 字,大约阅读时间需要 3 分钟。

多核系统中,读取-修改-写入操作序列的原子性问题

在多核系统中,读取-修改-写入操作序列面临着严峻的挑战。在多个CPU同时执行同一操作时,可能出现数据覆盖问题。这种情况不仅限于多核系统,还可能在单核系统中由于多线程控制路径交错引发。

1. 读取-修改-写入操作的常见问题

在多核系统中,两个或多个CPU同时读取同一内存变量的值。此时,读取操作可能返回旧值。随后,修改操作由其中一个CPU执行。写入操作时,由于总线arbiter的限制,可能存在先写入再覆盖的情况,导致最终结果错误。

在单核系统中,同样存在内核控制路径交错的问题。例如,在系统调用的中断处理中,中断handler的写入操作可能被系统调用控制路径的写入操作覆盖。

2. 解决方案:原子操作

针对这种情况,内核提供了atomic_t类型。该类型定义了若干原子接口API函数,确保操作的原子性。

3. ARM架构中的实现

在ARM架构中,原子操作分为两类:支持SMP的ARMv6及以后的版本,以及仅支持单核的ARMv6之前的版本。对于支持SMP的版本,原子操作通过特殊的指令完成。对于UP,原子操作则通过关闭中断实现。

4. 汇编实现细节

以atomic_add为例,展示具体实现:

asm volatile (    : "%0 += %1"     : "r"    : "ir"    : "cc");

上述代码中,__volatile__用于防止优化。asm语句定义了一个嵌入式汇编接口,: "%0 += %1"表示将结果保存到输出操作数,"r"表示输出操作数为一个可写寄存器,"ir"表示输入操作数为一个早期覆盖寄存器。"cc"通知GCC汇编器条件码寄存器的变化。

5. 指令细节:LDREX和STREX

LDREX和STREX指令用于实现原子操作。LDREX从内存读取数据至寄存器,并放出两个监控dog。STREX用于写入内存,并根据结果返回状态。LDREX和STREX适用于非共享内存;对于共享内存,需要额外的机制确保互斥。

6. 实现中的关键注意事项

  • 寄存器分配output operand listinput operand list需明确区分,确保编译器正确分配寄存器。
  • 缓存预加载:在使用STREX前,需预加载相关内存至缓存以提高性能。
  • 异常处理:需检查写入结果,若失败则重复操作。
  • 通过以上方法,可以确保读取-修改-写入操作的原子性,从而避免数据错误。

    转载地址:http://rypk.baihongyu.com/

    你可能感兴趣的文章
    python 常量_零基础学Python系列之一:Python的变量与常量
    查看>>
    Python 并发编程
    查看>>
    Python编程入门基础及高级技能、Web开发、数据分析和机器学习与人工智能
    查看>>
    python 序列化操作
    查看>>
    Python 开发者,这 7 个 VS Code 插件极力推荐
    查看>>
    python手把手视频_硬货 | 手把手带你构建视频分类模型(附Python演练))
    查看>>
    python 录音左右声道_Python分离立体声wav压缩文件的左右声道
    查看>>
    Python 循环异或对文件进行加解密
    查看>>
    Python开发环境搭建(附VMware安装包及虚拟机环境)
    查看>>
    python 微信扫码登录_python实现微信第三方网站扫码登录(Django)
    查看>>
    Python 快速下载依赖
    查看>>
    python实现非参数统计的Cochran检验 (附完整源码)
    查看>>
    python 怎么验证是否安装成功 scrapy
    查看>>
    Python 手写数字识别-1
    查看>>
    Python实现接口自动化测试库(JSON与Requests)详解
    查看>>
    Python 手写数字识别-3-sklearn中的几种算法
    查看>>
    python实现SSIM和MSSSIM计算 (附完整源码)
    查看>>
    Python 打开文件注意事项
    查看>>
    python 批量修改文件名_python windows下批量修改文件名
    查看>>
    Python 抓取网页乱码问题 以及EXCEL乱码
    查看>>