解决竞态(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. 狄斯奎诺(dijkstra 模板)

    /*狄斯奎诺算法(dijkstra)<邻接表> */ #include<stdio.h> #include<string.h> #include<stdlib ...

  2. JavaScript 设计模式之建造者模式

    一.建造者模式概念解读 1.建造者模式概念文字解读 建造者模式可以将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示.也就是说如果我们用了建造者模式,那么用户就需要指定需要建造的类 ...

  3. 调试解决iOS内存泄漏

    这里讲述在没有ARC的情况下,如何使用Instruments来查找程序中的内存泄露,以及NSZombieEnabled设置的使用. 本文假设你已经比较熟悉Obj-C的内存管理机制. 实验的开发环境:X ...

  4. Python学习笔记——MySQL的基本操作(2)

    1 运算符操作(配合查.修.删操作) 数据库的语法结构 查:select  *  from 表名 where 字段名 运算符 数字/字符; 改:update 表名 set 字段名=值,... wher ...

  5. PO_员工主管审批模式详解(设定)

    2014-06-03 Created By BaoXinjian

  6. PLSQL_统计信息系列01_统计信息的概念和重要性

    2014-12-18 Created By BaoXinjian

  7. linux内核线程,进程,线程

    http://blog.csdn.net/dyllove98/article/details/8917197 Linux对于内存的管理涉及到非常多的方面,这篇文章首先从对进程虚拟地址空间的管理说起.( ...

  8. 基于KWIC 的keyword匹配算法(管道+过滤器模式下实现)

    以下是基于KWIC 的keyword匹配算法(管道+过滤器模式下实现) 关键部分的管道+过滤器 软件体系下的实现, 在非常多的keyword搜索平台都使用了这一 循环移位+排序输出的 keyword匹 ...

  9. List 集合remove问题

    java的list集合中.使用remove删除元素: 方法一: static List<Integer> list3 = new ArrayList<Integer>(); s ...

  10. ASP.NET Helper