博客
关于我
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/

    你可能感兴趣的文章
    SpringBoot中重写addCorsMapping解决跨域以及提示list them explicitly or consider using “allowedOriginPatterns“ in
    查看>>
    pageHelper分页工具的使用
    查看>>
    Palo Alto Networks PAN-OS身份认证绕过导致RCE漏洞复现(CVE-2024-0012)
    查看>>
    Panalog 日志审计系统 libres_syn_delete.php 前台RCE漏洞复现
    查看>>
    Panalog 日志审计系统 sprog_deletevent.php SQL 注入漏洞复现
    查看>>
    pandas :将时间戳转换为 datetime.date
    查看>>
    pandas DataFrame 中的自定义浮点格式
    查看>>
    Pandas 对数据框的布尔比较
    查看>>
    Pandas 读取具有浮点值的 csv 文件会导致奇怪的舍入和小数位数
    查看>>
    pandas 适用,但仅适用于满足条件的行
    查看>>
    Pandas-通过对列和索引的值求和来合并两个数据框
    查看>>
    pandas.read_csv()的详解-ChatGPT4o作答
    查看>>
    Pandas数据可视化怎么做?用实战案例告诉你!
    查看>>
    Pandas数据结构之DataFrame常见操作
    查看>>
    pandas整合多份csv文件
    查看>>
    pandas某一列转数组list
    查看>>
    Pandas模块,我觉得掌握这些就够用了!
    查看>>
    Pandas玩转文本处理!
    查看>>
    pandas的to_sql方法中使用if_exists=‘replace‘
    查看>>
    pandas读取parquet报错
    查看>>