linux并发concurrency控制
解决竞态(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控制的更多相关文章
- Linux Shell多进程并发以及并发数控制
1. 基础知识准备 1.1. linux后台进程 Unix是一个多任务系统,允许多用户同时运行多个程序.shell的元字符&提供了在后台运行不需要键盘输入的程序的方法.输入命令后,其后紧跟&a ...
- MySQL--InnoDB并发线程控制
InnoDB并发线程控制 MySQL InnoDB存储引擎提供innodb_thread_concurrency来控制进入InnoDB 存储引擎的线程数,以限制InnoDB存储引擎层的并发量. 当in ...
- linux并发服务器设计
linux 并发服务器: http://blog.csdn.net/ygl840455828ygl/article/details/52438167 http://www.2cto.com/os/20 ...
- Redis并发锁控制
为了防止用户在页面上重复点击或者同时发起多次请求,请求处理需要操作redis缓存,这个时候需要对并发边界进行并发锁控制,实现思路: 由于每个页面发起的请求带的token具备唯一性,可以将token作为 ...
- Server Develop (五) Linux并发模型
Linux并发模型 目前可以实现并发程序的方法有Apache模型(Process Per Connection,简称PPC),TPC(Thread PerConnection)模型,以及select模 ...
- Linux iptables 应用控制访问SSH服务
Title:Linux iptables 应用控制访问SSH服务 --2012-02-23 17:51 今天用到了以前从来没有用到过的,iptables控制访问,只允许外部访问SSH服务(22号端口 ...
- 并发(Concurrency)和并行(Parallelism)的区别
最近在读<real world haskell>里关于并行的一章时,看到作者首先对并发(Concurrency)和并行(Parallelism)的区别进行了定义和解释.以前我对这个问题也是 ...
- Linux并发模型
Linux并发模型 Linux并发模型 目前可以实现并发程序的方法有Apache模型(Process Per Connection,简称PPC),TPC(Thread PerConnection)模型 ...
- 并行(Parallelism)与并发(Concurrency)
并行(Parallelism):多任务在同一时刻运行.例如,多个任务在多核处理器上运行. 并发(Concurrency):两个或者两个以上的任务在一段时间内开始.运行.完成,这意味着它们不是在同一时刻 ...
随机推荐
- aop注解 事例
spring.xml中aop的配置 <!-- aop的配置 --> <aop:config> <!-- 切入点表达式 --> <aop:pointcut ex ...
- DP较为完整的知识
数位DP 这类题,才刚刚接触,记得去年网络赛,就有道这样的题,我完全不会, 对于这类题基本方法是,是利用数的位数来构造转移方程. 下面给出两篇论文的链接: <数位计数问题解法研究> < ...
- HDUOJ----A Computer Graphics Problem
A Computer Graphics Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (J ...
- UltraEdit程序设置添加到右键菜单
http://hellofs.blog.51cto.com/6109153/1180681 以前安装UltraEdit软件,在安装过程中选择将其添加到右键菜单,安装完成后就可以正常显示在右键菜单,这样 ...
- 项目里面加入redis单机版 和集群版的配置
第一步: 如果你是maven项目,你直接配置就可以了,如果不是需要下载这个包 jedis包 <!-- Redis 客户端 --> <dependency> ...
- Zookeeper监控工具
Zookeeper的常用开源监控工具可以参考:http://zqhxuyuan.github.io/2016/12/31/BigData-Monitor-Tool
- Linux内存初始化(四) 创建系统内存地址映射
一.前言 经过内存初始化代码分析(一)和内存初始化代码分析(二)的过渡,我们终于来到了内存初始化的核心部分:paging_init.当然本文不能全部解析完该函数(那需要的篇幅太长了),我们只关注创建系 ...
- Maven实战(九)---模块聚合和继承
类之间有聚合和继承关系,Maven也具备这种设计原则. 那么Maven的pom是怎样进行聚合与继承的呢? 一.什么是聚合?为什么要用聚合? 上一篇博客介绍了模块化的基本知识. 有了模块化,那么我们项目 ...
- 【C语言天天练(十三)】printf、fprintf、sprintf和snprintf函数
#include <stdio.h> int printf(const char *format, ...); int fprintf(FILE *stream, const char * ...
- Python maketrans() 方法
描述 Python maketrans() 方法用于给 translate() 方法创建字符映射转换表. 可以只接受一个参数,此时这个参数是个字典类型(暂不研究这种情况). 对于接受两个参数的最简单的 ...