开源世界操作系统原理os kernel

os临界区保护(critical region)以及mutex原

2019-07-29  本文已影响0人  cheng3100

什么是临界区保护?

临界区(critical region)是指一段特定的代码行为集合,其中可能包括对数据的修改,执行一段特定逻辑等等。

临界区的概念是因为并发编程(multiprogram)的出现导致的,当出现多个task、多个cpu、甚至网络中多个服务器对同一个逻辑对象操作时,就会有条件竞争出现,如果设对该逻辑对象的操作为A,此时必须对A做特殊保护,约定对这A的这种特殊保护统称为临界区保护(mutex exclue),称A操作的范围为临界区。

临界区不保护会出现什么问题?

举例说明,假设有两个task都执行如下代码:

// p is a global var
// ...
    if (p == NULL) {
        p = malloc(N);
    }
// .do some thing
    free(p);

这里至少有两个问题:

因此在这段代码前后都应作为临界区保护

临界区保护的原理

临界区保护有多种思路,比如可以重新设计任务改造为无锁算法、比如设计任务之间的执行顺序令不会出现同时访问临界区的情况等,但通用的思路一般是在令任务对临界区访问实现互斥,这种思路称为mutex锁。
mutex主要就2种操作,分别是加锁和解锁,我们这里设为P和V操作,那么上述代码应该改为

// p is a global var
// ...
    P(m);
    if (p == NULL) {
        p = malloc(N);
    }
// .do some thing
    free(p);
    V(m);

假设已经实现了P\V接口,则当任务1先获取锁P(m)成功后,此时如果任务2再获取P(m)会发生失败,系统会保证只有任务1释放锁后任务2才可以P成功并进入临界区。
那么mutex接口具体怎么实现呢?

mutex锁的实现原理

mutex锁的原理核心主要两个部分,分别是

这两个部分的具体实现在单核和多核平台、有无cache情况下又有较大区别,这里我们先以单核无cache为例说明

原子地判断并置位标志位

这里的标志位本身可以是一个普通内存变量,对于临界区保护而言只需要标志位有两个状态,比如0代表未被上锁,1代表已上锁,只是这里需要注意地是这个过程必须是”原子“的,假设我们这样实现P操作

    // Wrong mutex implement!
    bool P(mutex m)
    {
        if (m == 0) {
            m = 1;
            return true;
        }
        return false;
    }

敏锐的读者应该发现这个方式很显然行不通,原因和上面的例子一样,因为可能出现两个任务同步进入判断m是否为0的语句,同时获取到锁,也就没有起到保护作用。
分析起来根本原因就是mutex标志位的判断本身应该是原子性不可分割的,对于单核平台而言,只需要实现这个过程种没有发生调度切到其他任务即可,一般可以通过关中断实现,

    // not complete mutex implement!
    bool P(mutex m)
    {
        LockInt();  // key step! ensure atomic!
        if (m == 0) {
            m = 1;
            UnLockInt();
            return true;
        }
        UnLockInt();
        return false;
    }

这样便保证了mutex的持有与否的判断是可用的了,但实际上这个实现还是有问题,这个就是对这个判断结果如何处理

对判断结果的处理策略

如果获取到锁,自然是继续往下执行。但如果获取不到锁应该如何处理呢?mutex以及各种变形的具体实现的差异主要就在这里,总体上,分为两种策略 switch/spin

进一步延生

以上只涉及到mutex以及各种变形实现的一个极其简化的基础框架,其中尤其涉及到对锁标志位的原子判断和处理策略在多核平台下有大量的实现方式和研究成果,后面有机会会再整理详述

如果希望阅读os对mutex的源码实现的朋友,建议先读一些RTOS的实现,其原理和思想与linux非常接近,而linux本身需要适配的场景和平台太多,有太多与核心思想无关的代码,尤其是各种适配宏,没有实现理解者很难读。

TIP 打个广告,本人作为开源操作系统Liteos的内核开发组人员,欢迎大家在github上下载使用!
liteos一个开源IOT系统

上一篇下一篇

猜你喜欢

热点阅读