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

linux同步方法剖析,Linux同步方法剖析(内核内各种锁机制一览)中

Linux同步方法如果您了解了一些基本理论并且明白了需要解决的问题,接下来将学习Linux支持并发和互斥锁的各种方法。在以前,互斥锁是通过禁用中断来提供

Linux 同步方法

如果您了解了一些基本理论并且明白了需要解决的问题,接下来将学习 Linux

支持并发和互斥锁的各种方法。在以前,互斥锁是通过禁用中断来提供的,但是这种形式的锁定效率比较低(现在在内核中仍然存在这种用法)。这种方法也不能进行扩展,而且不能保证其他处理器上的互斥锁。

在以下关于锁定机制的讨论中,我们首先看一下原子运算符,它可以保护简单变量(计数器和位掩码(bitmask))。然后介绍简单的自旋锁和读/写锁,它们构成了一个

SMP 架构的忙等待锁(busy-wait lock)覆盖。最后,我们讨论构建在原子 API 上的内核互斥锁。

(1)原子操作

Linux 中最简单的同步方法就是原子操作。原子意味着临界段被包含在 API 函数中。不需要额外的锁定,因为 API

函数已经包含了锁定。由于 C 不能实现原子操作,因此 Linux

依靠底层架构来提供这项功能。各种底层架构存在很大差异,因此原子函数的实现方法也各不相同。一些方法完全通过汇编语言来实现,而另一些方法依靠 c 语言并且使用 local_irq_save 和

local_irq_restore 禁用中断。

当需要保护的数据非常简单时,例如一个计数器,原子运算符是种理想的方法。尽管原理简单,原子 API

提供了许多针对不同情形的运算符。下面是一个使用此 API 的示例。

要声明一个原子变量(atomic variable),首先声明一个 atomic_t 类型的变量。这个结构包含了单个 int

元素。接下来,需确保您的原子变量使用 ATOMIC_INIT 符号常量进行了初始化。 在清单 1 的情形中,原子计数器被设置为

0。也可以使用 atomic_set function 在运行时对原子变量进行初始化。

清单 1.

创建和初始化原子变量

atomic_t my_counter ATOMIC_INIT(0);

... or ...

atomic_set( &my_counter, 0 );

原子 API 支持一个涵盖许多用例的富函数集。可以使用 atomic_read 读取原子变量中的内容,也可以使用

atomic_add 为一个变量添加指定值。最常用的操作是使用 atomic_inc

使变量递增。也可用减号运算符,它的作用与相加和递增操作相反。清单 2. 演示了这些函数。

清单 2. 简单的算术原子函数

val = atomic_read( &my_counter );

atomic_add( 1, &my_counter );

atomic_inc( &my_counter );

atomic_sub( 1, &my_counter );

atomic_dec( &my_counter );

该 API 也支持许多其他常用用例,包括 operate-and-test

例程。这些例程允许对原子变量进行操纵和测试(作为一个原子操作来执行)。一个叫做 atomic_add_negative

的特殊函数被添加到原子变量中,然后当结果值为负数时返回真(true)。这被内核中一些依赖于架构的信号量函数使用。

许多函数都不返回变量的值,但两个函数除外。它们会返回结果值( atomic_add_return 和

atomic_sub_return),如清单 3所示。

清单 3. Operate-and-test 原子函数

if (atomic_sub_and_test( 1, &my_counter ))

{

// my_counter is zero

}

if (atomic_dec_and_test( &my_counter )) {

// my_counter is zero

}

if (atomic_inc_and_test( &my_counter )) {

// my_counter is zero

}

if (atomic_add_negative( 1, &my_counter )) {

// my_counter is less than zero

}

val = atomic_add_return( 1, &my_counter ));

val = atomic_sub_return( 1, &my_counter

));

如果您的架构支持 64 位长类型(BITS_PER_LONG 是 64 的),那么可以使用 long_t atomic

操作。可以在 linux/include/asm-generic/atomic.h 中查看可用的长操作(long

operation)。

原子 API

还支持位掩码(bitmask)操作。跟前面提到的算术操作不一样,它只包含设置和清除操作。许多驱动程序使用这些原子操作,特别是

SCSI。位掩码原子操作的使用跟算术操作存在细微的差别,因为其中只有两个可用的操作(设置掩码和清除掩码)。使用这些操作前,需要提供一个值和将要进行操作的位掩码,如清单

4 所示。

清单 4. 位掩码原子函数

unsigned long my_bitmask;

atomic_clear_mask( 0, &my_bitmask );

atomic_set_mask( (1<<24),

&my_bitmask );



推荐阅读
  • 主板IO用W83627THG,用VC如何取得CPU温度,系统温度,CPU风扇转速,VBat的电压. ... [详细]
  • 深入解析Serverless架构模式
    本文将详细介绍Serverless架构模式的核心概念、工作原理及其优势。通过对比传统架构,探讨Serverless如何简化应用开发与运维流程,并介绍当前主流的Serverless平台。 ... [详细]
  • ElasticSearch 集群监控与优化
    本文详细介绍了如何有效地监控 ElasticSearch 集群,涵盖了关键性能指标、集群健康状况、统计信息以及内存和垃圾回收的监控方法。 ... [详细]
  • 本文深入探讨了SQL数据库中常见的面试问题,包括如何获取自增字段的当前值、防止SQL注入的方法、游标的作用与使用、索引的形式及其优缺点,以及事务和存储过程的概念。通过详细的解答和示例,帮助读者更好地理解和应对这些技术问题。 ... [详细]
  • 本文详细介绍了Grand Central Dispatch (GCD) 的核心概念和使用方法,探讨了任务队列、同步与异步执行以及常见的死锁问题。通过具体示例和代码片段,帮助开发者更好地理解和应用GCD进行多线程开发。 ... [详细]
  • 探讨如何修复Visual Studio Code中JavaScript的智能感知和自动完成功能在特定场景下无法正常工作的问题,包括配置检查、语言模式选择以及类型注释的使用。 ... [详细]
  • 深入解析RDMA中的队列对(Queue Pair)
    本文将详细探讨RDMA架构中的关键组件——队列对(Queue Pair,简称QP),包括其基本概念、硬件与软件实现、QPC的作用、QPN的分配机制以及用户接口和状态机。通过这些内容,读者可以更全面地理解QP在RDMA通信中的重要性和工作原理。 ... [详细]
  • 探讨ChatGPT在法律和版权方面的潜在风险及影响,分析其作为内容创造工具的合法性和合规性。 ... [详细]
  • 优化SQL Server批量数据插入存储过程的实现
    本文介绍了一种改进的SQL Server存储过程,用于生成批量插入语句。该方法不仅提高了性能,还支持单行和多行模式,适用于SQL Server 2005及以上版本。 ... [详细]
  • 本文深入探讨了MySQL中常见的面试问题,包括事务隔离级别、存储引擎选择、索引结构及优化等关键知识点。通过详细解析,帮助读者在面对BAT等大厂面试时更加从容。 ... [详细]
  • 本文详细介绍了如何在 Android 中使用值动画(ValueAnimator)来动态调整 ImageView 的高度,并探讨了相关的关键属性和方法,包括图片填充后的高度、原始图片高度、动画变化因子以及布局重置等。 ... [详细]
  • MySQL DATETIME 类型长度及使用指南
    本文详细介绍了 MySQL 中 DATETIME 类型的长度要求及其格式规范,并补充了其他常见数据类型的说明,帮助开发者更好地理解和使用这些类型。 ... [详细]
  • 本文详细对比了Windows 7家庭高级版与旗舰版之间的主要区别,包括技术支持期限、硬件兼容性及特色功能等方面。 ... [详细]
  • 在寻找轻量级Ruby Web框架的过程中,您可能会遇到Sinatra和Ramaze。两者都以简洁、轻便著称,但它们之间存在一些关键区别。本文将探讨这些差异,并提供详细的分析,帮助您做出最佳选择。 ... [详细]
  • 本文探讨了在JavaScript中数字运算和位运算之间的性能差异,分析了两者的工作原理及影响性能的关键因素。 ... [详细]
author-avatar
naozhewaner_254
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有