zoukankan      html  css  js  c++  java
  • 内核中的锁


    内核进程的竞争:
        加锁:
           
        等锁的三种方法:
            1.如果没有锁,不等解锁直接返回
            2.如果没有锁,就睡着等待解锁,当拿到锁之后,就会被唤醒,这种就是睡眠锁   ----》信号量 / 互斥体
            3.如果没有锁,就一直要锁,这种最消耗cpu资源    ----》 自旋锁 ,举个例子:如果有两个人(进程),一个进门去喝水了,先把门锁住(加锁),喝着喝着,然后另一个人又敲门,他想进来喝水,但是现在门还没有解锁,然后他就一直敲门(消耗资源),直到等到另一个人出来(解锁)。

    /arm_emb/sync_way :

    同步的方法:

        处于进程上下文的,自旋锁和互斥体和信号量都能用,加锁力度比较小,一般选用自旋锁。
        注意:这里所说的加锁力度就是,举个例子假如说一个人进门喝水的时候,他一进门就把门锁住了 (加锁),然后自己以很短的时间就把水喝完了,而另一个人也想进来喝水,门还没开但是距离开门 (解锁) 的时间很短了,假如说他现在睡了,然后另外一个人又立马解锁了,这个时候他又要被唤醒,这就有点消耗资源,所以用自旋锁比较好,敲一会门,然后就开了

        处于中断上下文的,必然选择用自旋锁,不能使用原子操作,如果给中断中加入


        1.自旋锁:    非睡眠锁,中断上下文,必然是自旋锁,但是这个最消耗cpu资源

        /******************************************/

        进程和进程间的竞争
        
        spinlock_t spin;
        
        spin_lock_init(&spin);
        
        //加锁
        spin_lock(&spin);
        
        //解锁
        spin_unlock(&spin);

        /*******************************************/

        中断和进程的竞争
        
        注意:cpsid i //汇编就是将 cpsr 寄存器的第 i 位置 1
        
        spinlock_t spin;
        
        //禁止中断并加锁
        spin_lock_irqsave(&spin,cpsr);
        
        //解锁并恢复中断
        spin_unlock_irqrestore(&spin,cpsr);

        /******************************************/
        
        中断的下半部和进程之间的竞争
        
        spinlock_t spin;
        
        //禁止中断下半部并加锁
        spin_lock_bh(&spin);
        
        //解锁并恢复中断下半部
        spin_unlock_bh(&spin);
        
        /*******************************************/


            
        2.互斥体:  睡眠锁,只允许锁的持有者只有一个

        /******************************************/
        进程和进程间的竞争
        
        struct mutex mutex;
        
        mutex_init(&mutex);
        
        //加锁
        mutex_lock(&mutex);
        
        //解锁
        mutex_unlock(&mutex);
        
        /******************************************/


        3.信号量:    睡眠锁,可以设置锁的持有者个数

        /*******************************************/
        进程和进程间的竞争
        
        //实例化信号量的结构体
        struct semaphore sema;
        
        // @ val 锁的持有者的个数
        static inline void sema_init(struct semaphore *sem, int val)
        
        //加一操作
        down();
        //减一操作
        up();

        //尝试获得信号量,不等待
        down_trylock();

        
        /******************************************/

            
        4.原子操作: 针对全局的整型的变量,比如在做 i++ 操作的时候,会出现竞争,这就需要原子操作

            //v 是原子类型的全局变量
            atomic_t v;

            //如果返回 0 表示原子操作失败,
            if (!atomic_dec_and_test(&v)) {
                atomic_inc(&v);    //
              return -EBUSY;
            }
                
            atomic_inc(&mydev.v);


    中断和进程的加锁解锁:

        bne 1b  //不相等的话,则跳转到此行以上的 1 标号那里去

        ldrex 的这个 ex 表示内存独占

        中断产生 GIC 不停的给 cpu 触发中断
        

  • 相关阅读:
    来自网络的双参求范围问题,没有单参求范围那么有套路!
    svn更改用户问题
    html控件中上传文件的技巧
    认识jsp
    dom4j 解析XML文件
    BaseDao优化
    JDBC连接数据库
    javascript常用函数
    jQuery formValidator(插件)
    javascriptDetect对象封装
  • 原文地址:https://www.cnblogs.com/winfu/p/5548458.html
Copyright © 2011-2022 走看看