内核控制路径:内核处理不同种类的中断所执行的指令序列
内核控制路径所充当的角色与进程相似,二者之间的区别在于前者更基本:首先,没有任何描述符与内核控制路径有关;其次,内核控制路径不是通过单个函数进行调度,而是通过把停止和回复路径的指令序列插入到内核的代码中进行调度。
在交错执行内核控制路径时,要特别注意那些包含几个相关变量的数据结构。
本章包括一下几个部分
1: 什么时候同步是不必要的 2:原子操作 3: 内存屏障 4:自旋锁 5 :读写自旋锁 6 :大读者锁 7:信号量 8 读写信号量 9 补充原语 10 :本地中断禁止 11:全局终端禁止 12:对内核数据结构的同步访问 13: 在自旋锁,信号量及中断禁止之间选择 14: 避免竞争的实例
下面详细介绍各部分的具体的内容
运行在内核态的进程是不能被另一个进程替代的而中断可以中断内核进程,同时内核控制路径不能被执行可延迟函数后系统调用的其他内核控制路径所中断。
2 原子操作
首先分类接受了x86指令和他们是否是原子性操作。
为了保证一些程序操作的原子性,linux内核提供了一个专门的atomic_t类型和一些专门的函数,这些函数作用于atomic_t类行的变量,并当作单独的,原子的汇编指令来实现。在多处理器系统中,每一条这样的指令都有一个lock字节的前缀。
3 内存屏障
首先说明了在编译器优化程序的时候,指令代码并不是严格按照他们在源码中出现的顺序执行。它会对程序重新排序。此外,现在的cpu并行执行并且要并行的内存访问。因此引入了内存屏障(memory barrier) 在原语之后的操作开始执行之前,原语的操作已经完成。一次内存屏障类似于防火墙,任何汇编语言都不能通过。前面所说的原子操作都起到内存屏障的作用。
4:自旋锁
自选锁的加入保护几个内核控制路径进入临界区,对数据的操作。
spin_lock()循环,直到自旋锁变为1(未锁),然后,把自旋锁置为0(锁上)
spin_unlock() 把自旋锁置为1 (未锁)
spin_lock_init() 把自旋锁置为1
spin_unlock_wait() 等待,直到自旋锁变为1
spin_is_locked() 如果自旋锁被置为1 ,返回0;否则,返回1
spin_trylock() 把自旋锁置为0, 如果获取,则返回1;否则,返回0
5: 读写自旋锁
读写自旋锁的引入增加了内核的并发功能。每个读写自旋锁都是一个rwlock_t结构,其lock字段是一个32位的字段,24位记录并发读操作的内核控制路径的数目。 还有一个未锁标志字段。read_lock为读获取或释放一个锁,为写获取或释放一个锁write_lock()。
6:大读者锁
阅读(1418) | 评论(0) | 转发(0) |