解决竞态(race conditions)最根本的途径是对共享资源的互斥访问,访问共享资源的代码区被称为临界区(critical sections),对临界区的代码需要以某种互斥机制加以保护。
常见的互斥机制有:中断屏蔽、原子操作、自旋锁、信号量、互斥体。

1. 中断屏蔽
由于linux内核的进程调度和异步IO等操作都是依赖中断来实现的,所以中断屏蔽也可以避免内核强占进程之间的竞态发生。
定义在linux/irqflags.h,实现在asm/irqflags.h中。
local_irq_disable();
local_irq_enable();

local_irq_save(flags);
local_irq_restore(flags);

local_bh_disable();
local_bh_enable();

2. 原子操作
原子操作分类:整型原子操作和位原子操作
整型原子操作
asm/atomic.h
void atomic_set(atomic_t *v, int i);
atomic_t v = ATOMIC_INIT(0);
atomic_read(atomic_t *v);
void atomic_add(int i, atomic_t *v);
void atomic_sub(int i, atomic_t *v);
void atomic_inc(atomic_t *v);
void atomic_dec(atomic_t *v);
int atomic_inc_and_test(atomic_t *v);
int atomic_dec_and_test(atomic_t *v);
int atomic_sub_and_test(atomic_t *v);
操作后测试是否为0,为0返回true,否则返回false。
int atomic_add_return(int i, atomic_t *v);
操作后返回新值。

位原子操作
asm/bitops.h
void set_bit(nr, void *addr);
void clear_bit(nr, void *addr);
void change_bie(nr, void *addr);
test_bit(nr, void *addr);
int test_and_set_bit(nr, void *addr);
int test_and_clear_bit(nr, void *addr);
int test_and_change_bit(nr, void *addr);

3. 自旋锁
1)自旋锁主要针对SMP或单CPU且内核可强占的情况,对于单CPU且内核不可强占的系统自旋锁退化为空操作。
2)在单CPU且内核可强占的系统中,自旋锁持有期间内核的强占被禁止。

使用注意:
1)不能递归持有自旋锁。
2)持有自旋锁后不能阻塞。

linux/spinlock_types.h
spinlock_t lock;
spin_lock_init(&lock);
spin_lock(&lock);
spin_trylock(&lock);
spin_unlock(&lock);

spin_lock_irq();
spin_unlock_irq();
spin_lock_irqsave();
spin_unlock_irqrestore();
spin_lock_bh();
spin_unlock_bh();

读写自旋锁
写操作时最多只能有一个写进程。
顺序锁

4. 信号量
linux/semaphore.h,实现在ipc/sem.c和kernel/semaphore.c中。
struct semaphore sem;
void sema_init(struct semaphore *sem, int val);
void down(struct semaphore *sem);
int down_interruptible(struct semaphore *sem);
int down_trylock(struct semaphore *sem);
void up(struct semaphore *sem);

5. 互斥体
linux/mutex.h       kernel/mutex.c
struct mutex mymutex;
mutex_init(&mymutex);
void fastcall mutex_lock(struct mutex *lock);
int fastcall mutex_lock_interruptible(struct mutex *lock);
int fastcall mutex_trylock(struct mutex *lock);
void fastcall mutex_unlock(struct mutex *lock);

总结
1、信号量是进程级的,用于多个进程之间对资源的互斥。如果竞争失败,会发生进程上下文切换,当前进程进入休眠状态。
2、自旋锁得不到锁时会在原地自旋一直到获取锁,它节省了上下文的切换时间,所以一般用于要保护的临界区访问时间比较短的时候,否则会降低系统效率。

自旋锁和信号量选用原则
1、临界区执行时间比较小时,采用自旋锁,否则使用信号量。
2、信号量所包含的临界区包含可能引起阻塞的代码,而自旋锁要绝对避免在临界区使用阻塞代码。
3、信号量运用进程上下文,若要运于中断中,应用down_trylock()方式进行,不能获取就立即返回,避免阻塞。

参考:

1. linux设备驱动开发详解 宋宝华

2. linux并发控制

linux并发concurrency控制的更多相关文章

  1. Linux Shell多进程并发以及并发数控制

    1. 基础知识准备 1.1. linux后台进程 Unix是一个多任务系统,允许多用户同时运行多个程序.shell的元字符&提供了在后台运行不需要键盘输入的程序的方法.输入命令后,其后紧跟&a ...

  2. MySQL--InnoDB并发线程控制

    InnoDB并发线程控制 MySQL InnoDB存储引擎提供innodb_thread_concurrency来控制进入InnoDB 存储引擎的线程数,以限制InnoDB存储引擎层的并发量. 当in ...

  3. linux并发服务器设计

    linux 并发服务器: http://blog.csdn.net/ygl840455828ygl/article/details/52438167 http://www.2cto.com/os/20 ...

  4. Redis并发锁控制

    为了防止用户在页面上重复点击或者同时发起多次请求,请求处理需要操作redis缓存,这个时候需要对并发边界进行并发锁控制,实现思路: 由于每个页面发起的请求带的token具备唯一性,可以将token作为 ...

  5. Server Develop (五) Linux并发模型

    Linux并发模型 目前可以实现并发程序的方法有Apache模型(Process Per Connection,简称PPC),TPC(Thread PerConnection)模型,以及select模 ...

  6. Linux iptables 应用控制访问SSH服务

    Title:Linux iptables 应用控制访问SSH服务  --2012-02-23 17:51 今天用到了以前从来没有用到过的,iptables控制访问,只允许外部访问SSH服务(22号端口 ...

  7. 并发(Concurrency)和并行(Parallelism)的区别

    最近在读<real world haskell>里关于并行的一章时,看到作者首先对并发(Concurrency)和并行(Parallelism)的区别进行了定义和解释.以前我对这个问题也是 ...

  8. Linux并发模型

    Linux并发模型 Linux并发模型 目前可以实现并发程序的方法有Apache模型(Process Per Connection,简称PPC),TPC(Thread PerConnection)模型 ...

  9. 并行(Parallelism)与并发(Concurrency)

    并行(Parallelism):多任务在同一时刻运行.例如,多个任务在多核处理器上运行. 并发(Concurrency):两个或者两个以上的任务在一段时间内开始.运行.完成,这意味着它们不是在同一时刻 ...

随机推荐

  1. ubuntu简易部署Python3编写的djangoWeb应用

    1.更新软件源 sudo apt-get update 2.安装Python3 sudo apt-get install python3 安装Python3之后建议不要修改此命令的名称,保持pytho ...

  2. 浅谈软件配置管理工具(github & SVN)

    1   配置管理名词定义 1.1 配置项 软件生存周期各个阶段活动的产物经审批后即可称之为软件配置项. 软件配置项包括: ①与合同.过程.计划和产品有关的文档和资料: ②源代码.目标代码和可执行代码: ...

  3. MFC中创建多线程

    1.   列举几种进程的同步机制,并比较其优缺点. 原子操作    信号量机制   自旋锁    管程,会合,分布式系统 2.   进程之间通信的途径 共享存储系统       消息传递系统      ...

  4. 由SQL Server的job出错调查引起的思考

            最近一段时间数据库上的一个Job频繁报错,刚开始我们没有抽时间进行彻底的调查.只是处理了下不规范的数据 就没有管了,但是后面我们发现过了几天它又报错了.         今天我进行了彻 ...

  5. Android特性与系统架构

    Android特性与系统架构 一.Android特性 • 应用程序框架支持组件的重用与替换 • Dalvik 虚拟机专为移动设备优化 • 集成的浏览器基于开源的WebKit 引擎 • 优化的图形库包括 ...

  6. Python endswith() 方法

    描述 endswith() 方法用于判断字符串是否以指定后缀结尾,如果是则返回 True,否则返回 False. 语法 endswith() 方法语法: S.endswith(suffix[,star ...

  7. RabbitMQ 远程 IP 访问 解决办法 -摘自网络

    刚刚安装的RabbitMQ-Server-3.3.5,并且也已经开启了Web管理功能,但是现在存在一个问题: 出于安全的考虑,guest这个默认的用户只能通过http://localhost:1567 ...

  8. Oracle学习笔记之四,SQL语言入门

    1. SQL语言概述 1.1 SQL语言特点 集合性,SQL可以的高层的数据结构上进行工作,工作时不是单条地处理记录,而对数据进行成组的处理. 统一性,操作任务主要包括:查询数据:插入.修改和删除数据 ...

  9. [Jobdu] 题目1214:丑数

    题目描述: 把只包含因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含因子7.习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 输入: 输 ...

  10. CSS中overflow:scroll怎么设置只上下滚动而不左右滚动

    CSS中"overflow:scroll"默认是左右,上下都滚动.怎么设置只上下滚动而不左右滚动,下面有个不错的解决方法 CSS中"overflow:scroll&quo ...