文档章节

内核并发处理

首席吹牛官
 首席吹牛官
发布于 2015/05/22 12:50
字数 992
阅读 9
收藏 0

随着硬件的发展,SMP(对称多处理器)已经很普遍,如果内核的调度机制是可抢占的,那么SMP和内核抢占是多线程执行的两种场景。当多个线程同时访问内核的数据结构时,我们就需要对其做串行化处理。

自旋锁和互斥体

访问共享资源的代码区称为临界区。自旋锁(spinlock)和互斥体(mutex, mutual exclusion)是保护内核临界区的两种基本机制。

自旋锁可以确定在同时只有一个线程进入临界区。其他想进入临界区域的线程(执行线程)必须不停的在原地打转,知道第一个线程释放的自旋锁。下面是spinlock的用法

#include <linux/spinlock.h>

/*初始化*/
spinlock_t  _lock = SPIN_LOCK_UNLOCKED;

/*上锁*/
spin_lock(&_lock);

/*临界区代码*/


/*释放锁*/
spin_unlock(&_lock);
互斥体与自旋锁不一样,当在临界区外等待时,它不会不停的打转,而是使当前的线程进入睡眠状态。如果执行临界区需要很长的时间,那么互斥体更适合自旋锁,这样可是更好的利用cpu,而不是长时间在哪里打转。

那对于这两个怎么取舍?

1.如果临界区需要睡眠,只能使用互斥体,因为在获得自旋锁后进行调度、抢占以及在等待队列上睡眠都是非法的。

2.由于互斥体会在面临竞争的情况下将当前的线程置于睡眠状态,因此,在中断处理函数中只能使用自旋锁。

下面是互斥体的使用方法

#include <linux/mutex.h>

static DEFINE_MUTEX(_mutex);


mutex_lock(&_mutex);

/*  临界区*/

mutex_unlock(&_mutex)

下面从四个案例中,讨论内核并发保护。

1.进程上下文,单cpu,非抢占式内核

这种是最简单的,不需要加锁

2.进程和中断上下文,单cpu,非抢占式内核

这种情况下,在保护临界区的时候,仅仅只需要对中断禁止。单cpu和非抢占式内核决定进程不会切换,可是在临界区时,进程可能被中断打断,所以需要禁止中断,也就是在进入临界区时保存中断状态,离开临界区后恢复中断状态。

3.进程和中断上下文,单cpu,抢占式内核

这种情况与2相比,内核可抢占,那么就需要对临界区加锁来禁止内核的抢占,中断还是和2一样。

4.进程和中断上下文,SMP,抢占式内核

现在执行在SMP机器上,而且你的内核配置了CONFIG_SMP和CONFIG_PREEMPT。在SMP系统中,获得自旋锁时,仅仅本CPU的中断被禁止,然后进程上下文和中断处理函数可以在不同的CPU上进行,所以非本CPU的中断处理函数需要等待本CPU上的进程上下文代码推出临界区。中断上下文中需要使用spin_lock和spin_unlock。

原子操作

原子操作用于执行轻量级的,仅执行一次的操作,例如修改定时器、有条件的增加值,设置位等。原子操作可是实现操作的串行化,也就不许要加锁处理。原子操作的时间取决了体系结构。

读写锁

自旋锁的变体--读写锁。如果每个执行单元在访问临界区的时候要么是读要么是写数据结构,但是他们都不会同时进行读写操作,那么读写锁很适合。读写锁允许同一时候多个线程进入临界区,但如果一个写线程进入临界区,那么其他的读写进程都必须等待。读写锁使用方法:

rwlock_t _rwlock = RW_LOCK_UNLOCKED;


read_lock(&_rwlock);

/* 临界区代码*/

read_unlock(&_rwlock);


--------------------------------------

rwlock_t _rwlock = RW_LOCK_UNLOCKED;


wirte_lock(&_rwlock);

/* 临界区代码*/

wirte_unlock(&_rwlock);


本文转载自:http://blog.csdn.net/zhx6044/article/details/9328051

首席吹牛官
粉丝 9
博文 368
码字总数 191938
作品 0
闵行
程序员
私信 提问
并发一:JAVA并发模型

一、并发 并发程序是指在运行中有两个及以上的任务同时在处理,与之相关的概念并行,是指在运行中有两个及以上的任务同时执行,差别是在于处理和执行。在单核CUP中两个及以上任务的处理方式是...

wangjie2016
2017/05/18
0
0
千万并发的秘密-内核是问题的根本

我们现在已经搞定了 C10K并发连接问题 ,升级一下,如何支持千万级的并发连接?你可能说,这不可能。你说错了,现在的系统可以支持千万级的并发连接,只不过所使用的那些激进的技术,并不为人...

葱油拌面
2013/05/15
24.7K
40
nginx优化篇之Linux 内核参数的优化 (2)

原博客地址(欢迎访问):http://www.loveyqq.tk/blog/2014/05/27/nginxyou-hua-pian-zhi-linux-nei-he-can-shu-de-you-hua/ 由于默认的Linux内核参数考虑的是最通用的场景,这明显不符合用于支...

NILYANG
2015/04/16
558
0
服务器模型——从单线程阻塞到多线程非阻塞(上)

前言的前言 服务器模型涉及到线程模式和IO模式,搞清楚这些就能针对各种场景有的放矢。该系列分成三部分: 单线程/多线程阻塞I/O模型 单线程非阻塞I/O模型 多线程非阻塞I/O模型,Reactor及其...

2017/12/21
0
0
Reactor和Proactor模式

在高性能的I/O设计中,有两个比较著名的模式Reactor和Proactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作。 同步和异步 同步和异步是针对应用程序和内核的交互而言的,...

ksfzhaohui
2012/12/14
337
0

没有更多内容

加载失败,请刷新页面

加载更多

从零基础到拿到网易Java实习offer,我做对了哪些事

作为一个非科班小白,我在读研期间基本是自学Java,从一开始几乎零基础,只有一点点数据结构和Java方面的基础,到最终获得网易游戏的Java实习offer,我大概用了半年左右的时间。本文将会讲到...

Java技术江湖
昨天
5
0
程序性能checklist

程序性能checklist

Moks角木
昨天
7
0
VUE 计算属性

本文转载于:专业的前端网站▶VUE 计算属性 1、示例代码 <!DOCTYPE html><html lang="zh"> <head> <meta charset="UTF-8" /> <title>vue示例</title> </hea......

前端老手
昨天
6
0
快速搭建LNMT平台和环境部署 Tomcat详解

Tomcat部署的基本概念 1. CATALINA_HOME与CATALINA_BASE分别指什么?     CATALINA_HOME指的是Tomcat的安装目录     bin:\\Tomcat一些脚本存放目录,比如启动脚本startup.bat/start...

网络小虾米
昨天
7
0
float浮动

float浮动 float浮动概念及原理: 文档流:文档流是文档中可显示对象在排列时所占用的位置。 加浮动的元素,会脱离文档流,会沿父容器靠左或靠右排列,如果之前已经有浮动的元素,会挨着浮动...

studywin
昨天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部