linux内核就相当于不断对请求进行响应的服务器,这些请求可能来自CPU,可能来自发出中断的外部设备。我们将内核看作两种请求的侍者。

(1)老板提出请求,侍者如果空闲,为老板服务。(系统调用或异常)

(2)侍者正在无顾客服务时,老板提出请求,则转去为老板服务。(中断异常嵌套)

(3)侍者正为老板服务时,另一老板提出请求,此时转去为另一个老板服务,回头再给这个老板服务。(中断嵌套)

(4)老板可命令老板停止为当前客户服务,侍者完成老板请求之后,可能为新选中的顾客服务。(内核抢占)

内核抢占特点:一个内核态运行的进程,可以被执行内核函数期间被另一个进程取代。有关内核抢占参照本文:内核抢占

同步概念

      临界区是一段代码,进入临界区的内核控制路径必须全部执行这段代码,其他控制路径才能进入临界区。单核cpu可以通过简单的关闭中断、禁止内核抢占来进行保证临界区的互斥访问,多cpu就不行 了。

下列条件不需要同步:

(1)执行中断的内核路径不可能被可延迟或系统调用服务例程内核路径所中断,所以不需要同步;

(2)软中断和tasklet不能再同一个CPU上交替执行,所以仅这两者存在时,不需要同步;

(3)仅被一种tasklet访问的数据结构不需要同步。

同步原语

1.每CPU变量

最重要的同步技术就是把内核变量声明为每CPU变量,每CPU变量主要是数据结构的数组,系统每个CPU对应数组的一个元素。一个CPU不应该访问与其他CPU对应的数组元素。每个CPU可以随意修改自己的元素不用担心出现竞争条件。每CPU变量对来自异步函数(中断和可延迟函数)的访问不提供保护,在这种情况下需要提供另外的同步原语。内核抢占可导致每CPU变量产生竞争条件。

2.原子操作

这样的操作是芯片原子级的,执行这样的指令,中间不能中断,且避免其他的CPU访问同样的内存单元。这种原子操作,通过“锁定”内存总线实现,直到这条指令执行结束为止,其他处理器不能访问该内存单元。原子操作:

atom_read(v),atom_set,atom_add,atom_sub.....

3.优化和内存屏障

     当使用编译器的时候,编译器可能重新安排汇编语言指令以使寄存器以最优的方式执行。当处理同步时,必须避免指令重新排序。可通过设置内存屏障,确保原语之后的操作语句执行之前,原语操作之前的语句已经完成,这样保证汇编语句顺序执行。

4.自旋锁

     自旋锁是用来多处理环境中的一种特殊锁。如果内核路径发现锁是开着的,则可获取锁进入临界区。相反如果内核路径发现锁由另一个CPU上的控制路径所持有,则在周围“旋转”(其实,占着cpu死等,等到为止)。

自旋锁的循环指令表示“忙等”(这种忙等,是nop操作,经过linux优化了,说是节省能源)。注意,在忙等期间,内核抢占有效,就是等待的进程可能被其他进程替代。一般来说,由自旋锁所保护的每个临界区都是禁止内核抢占的。

spinlock_t含有的两个字段:

slock;自旋锁的状态,1表示未加锁

break_lock:表示有无等待该锁的进程

提供的操作:

spin_lock_init();//初始化一把锁

spin_lock();//循环试图获得自旋锁

spin_unlock();//释放锁

spin_unlock_wait();//等待锁

spin_is_locked();//判断锁释是否被持有

5.读写自旋锁

      读写锁是为了增加内核的并发能力。该锁的特点:读者进程可以同时多个进入临界区;写者只能一个进入临界区(有写者的时候,读者无法进入)。读者和写者具有相同的优先权。

读/写自旋锁是一个rwlock_t结构。有read_lock和write_lock。

6.顺序锁

     读/写自旋锁中,读者和写者具有相同的优先权。事实上,可以这样,即使读者在读的时候,也可以让写者继续进行,这种策略,写者永远不会等待。但是,读者需要对所读到的东西检查,检查是否有被某个写者修改,一旦发现被修改,要重新读取。

7.读-拷贝-创新(RCU)

写者要写的时候,拷贝一份出来写,然后拷回去。

8.信号量

信号量其实也是为了实现互斥和同步(无外乎就是一种P/V操作封装)。但是,信号量中的进程一旦发现资源不可用时,就将自己挂起进入睡眠状态,这不是一种忙等。

然后,使用该资源的进程使用结束后,唤醒正在等待的进程,ok,同步完毕。

linux提供两种信号量:(1)内核信号量,由内核控制路径控制;(2)System V IPC信号量,用户态进程使用。

9.信号量

     跟信号量是一样的,但是允许多个读者同时进入设计的,你懂的。

linux内核笔记-内核同步的更多相关文章

  1. 趣谈linux操作系统笔记-内核初始化

    内核的启动从入口函数 start_kernel() 开始.在 init/main.c 文件中,start_kernel 相当于内核的main 函数.打开这个函数,你会发现,里面是各种各样初始化函数 X ...

  2. Linux内核笔记--内存管理之用户态进程内存分配

    内核版本:linux-2.6.11 Linux在加载一个可执行程序的时候做了种种复杂的工作,内存分配是其中非常重要的一环,作为一个linux程序员必然会想要知道这个过程到底是怎么样的,内核源码会告诉你 ...

  3. 【转载】linux内核笔记之进程地址空间

    原文:linux内核笔记之进程地址空间 进程的地址空间由允许进程使用的全部线性地址组成,在32位系统中为0~3GB,每个进程看到的线性地址集合是不同的. 内核通过线性区的资源(数据结构)来表示线性地址 ...

  4. 【转载】linux内核笔记之高端内存映射

    原文:linux内核笔记之高端内存映射 在32位的系统上,内核使用第3GB~第4GB的线性地址空间,共1GB大小.内核将其中的前896MB与物理内存的0~896MB进行直接映射,即线性映射,将剩余的1 ...

  5. 深入理解Linux内核-内核同步

    内核基本的同步机制: 抢占内核的主要特点:一个在内核态运行的进程,可能在执行内核函数期间被另外一个进程取代. 内核抢占:Linux 2.6允许用户在编译内核的时候配置十分启用 进程临界区:每个进程中访 ...

  6. Linux学习笔记:【004】Linux内核代码风格

    Chinese translated version of Documentation/CodingStyle   If you have any comment or update to the c ...

  7. Linux 2.6内核中新的锁机制--RCU

    转自:http://www.ibm.com/developerworks/cn/linux/l-rcu/ 一. 引言 众所周知,为了保护共享数据,需要一些同步机制,如自旋锁(spinlock),读写锁 ...

  8. Linux网络编程&内核学习

    c语言: 基础篇 1.<写给大家看的C语言书(第2版)> 原书名: Absolute Beginner's Guide to C (2nd Edition) 原出版社: Sams 作者: ...

  9. Linux下编译内核配置选项简介

    Code maturity level options代码成熟度选项 Prompt for development and/or incomplete code/drivers 显示尚在开发中或尚未完 ...

随机推荐

  1. 使用C语言实现字符串中子字符串的替换

    描述:编写一个字符串替换函数,如函数名为 StrReplace(char* strSrc, char* strFind, char* strReplace),strSrc为原字符串,strFind是待 ...

  2. java与C#的简单比较

    刚刚看完java视频,做了个简单图: 新知识不多,大多是与以往知识的相互碰撞,一下做了java与C#的简单比较:                         Java C# 主类名与文件名 必须一 ...

  3. 跟我一起写 Makefile(一)

    跟我一起写 Makefile  陈皓 概述—— 什么是makefile?也许非常多Winodws的程序猿都不知道这个东西,由于那些Windows的IDE都为你做了这个工作,但我认为要作一个好的和pro ...

  4. Spring MVC程序

    Spring MVC程序(IDEA开发环境)   回顾Java平台上Web开发历程来看,从Servlet出现开始,到JSP繁盛一时,然后是Servlet+JSP时代,最后演化为现在Web开发框架盛行的 ...

  5. Delphi中JSon SuperObject 使用:数据集与JSON对象互转

    在delphi中,数据集是最常用数据存取方式.因此,必须建立JSON与TDataSet之间的互转关系,实现数据之间通讯与转换.值得注意的是,这只是普通的TDataset与JSON之间转换,由于CDS包 ...

  6. perl 获取文件内容里第一个AAA和最后一个AAA

    <pre name="code" class="html">[root@wx03 ~]# cat -n aaa 1 3`13 2 edqae 3 d ...

  7. linux下C/C++IDE比较——Code::Blocks

    工欲善其事,必先利其器.用了这么久的linux,现在比较主流的几个C/C++的IDE基本已都用过了,现在来对他们做一下简单的比较. 1.VIM首先要说的是VIM.我认为,VIM只是一个编辑器,不能算是 ...

  8. UVALive 2519 Radar Installation 雷达扫描 区间选点问题

    题意:在坐标轴中给出n个岛屿的坐标,以及雷达的扫描距离,要求在y=0线上放尽量少的雷达能够覆盖全部岛屿. 很明显的区间选点问题. 代码: /* * Author: illuz <iilluzen ...

  9. Js版游戏打砖块开发过程详细

    最近对js的小游戏开发来了兴趣,前段时间由于回答度娘知道的提问写了个贪吃蛇,虽然难度不大并不复杂,感觉还挺有意思.感觉小时候玩过的什么俄罗斯方块,坦克大战什么的都可以试着用js实现下,这天来了兴致又想 ...

  10. Linux账号管理(一)

    整理自<鸟哥的Linux私房菜>,整理者:华科小涛http://www.cnblogs.com/hust-ghtao/ 管理员的工作中,相当重要的一环就是“管理账号”.因为整个系统都是你在 ...