《Linux内核设计与实现》——内核同步介绍

一、临界区和竞争条件

 一)、相关介绍

  1、临界区就是访问和操作共享数据的代码段。


  2、如果两个执行线程有可能处于同一个临界区中同时执行,那么这就是程序包含的一个bug。如果这种情况发生了,就称它为竞争条件


  3、避免并发和防止竞争条件称为同步



 二)、竞争条件实例




二、加锁

 一)、相关介绍

  1、锁机制提供了一种方法确保一次有且只有一次对数据进行操作,或者当另一个线程对临界区标记时,就禁止(或者说锁定)其他访问。


  2、锁的使用是自愿的,非强制性的,它完全属于一种编程者自选的编程手段。


  3、Linux各种锁机制之间的区别主要在于:当锁已经被其他线程持有,因而不可用时的行为表现——一些锁被争用时会简单地执行忙等待,而另外一些锁会使当前任务睡眠直

         到锁可用为止。



 二)、造成并发执行的原因:

  1、中断——中断几乎可以在任何时刻异步发生,也就可能随时打断当前正在执行的代码。

  2、软中断和tasklet——内核能在任何时刻唤醒或调度软中断和tasklet,打断当前正在执行的代码。

  3、内核抢占——因内核具有抢占性,所以内核中的任务可能会被另一任务抢占。

  4、睡眠以及用户空间的同步——在内核执行的进程可能会睡眠,这就会唤醒调度程序,从而导致一个新的用户程序执行。

  5、对称多处理——两个或多个处理器可以执行代码。



 三)、了解要保护什么

  1、找出那些数据需要保护是关键所在。


  2、大多数内核树据结构都需要加锁。有一个很好的经验可以帮助我们判断:如果有其他执行线程可以访问这些数据,那么就给这些数据加上某种形式的锁;如果任何其他什么

        东西都能看到它,那么就要锁住它。记住,要给数据而不是代码加锁。




三、死锁

  1、死锁的产生需要一定条件:要有一个或多个执行线程和一个或多个资源,每个线程都在等待其中一个资源,但所有资源都已经被占用了,所有的线程都在相互等待,但它们

        永远不会释放已经占有的资源。于是任何线程都无法继续,这便意味着死锁的发生。


  2、避免死锁的简单规则:

    1)、按顺序加锁。

    2)、防止发生饥饿。

    3)、不要重复同一个锁。

    4)、加锁设计应求简单。




四、争用和扩展性

  1、锁的争用,或简称争用,是指当锁正在被占用时,有其他线程试图获得该锁。


  2、一个锁处于高度争用状态,就是指有多个线程在等待获得该锁。


  3、扩展性是对系统可扩展性的一个度量。


  4、一般来说,提高可扩展性是件好事,因可提高Linux在更大型的、处理能力更强大的系统上的性能。但一味的提高可扩展性,会导致在小型SMP和UP机器上的性能降低。


  5、可扩展性是很重要的,需要慎重考虑。关键在于,在设计锁的开始阶段就应该考虑到要保证良好的扩展性。

 

你可能感兴趣的:(linux内核)