• 锁开销


    一、互斥锁的开销主要在内核态与用户态的切换:

      申请锁时,从用户态进入内核态,申请到后从内核态返回用户态(两次切换);没有申请到时阻塞睡眠在内核态。使用完资源后释放锁,从用户态进入内核态,唤醒阻塞等待锁的进程,返回用户态(又两次切换);被唤醒进程在内核态申请到锁,返回用户态(可能其他申请锁的进程又要阻塞)。所以,使用一次锁,包括申请,持有到释放,当前进程要进行四次用户态与内核态的切换。同时,其他竞争锁的进程在这个过程中也要进行一次切换。

      进程上下文切换的直接消耗包括CPU寄存器保存和加载,需要调度时有内核调度代码的执行。

    二、自旋锁:

      与互斥锁不同的是自旋锁不会引起调用者睡眠。如果自旋锁已经被别的进程保持,调用者就轮询(不断的消耗CPU的时间)是否该自旋锁的保持者已经释放了锁("自旋"一词就是因此而得名)。

    三、互斥锁、自旋锁的使用场景:

    1.由于自旋锁使用者一般保持锁时间非常短,因此选择自旋而不是睡眠,自旋锁的效率远高于互斥锁。

    2.自旋锁保持期间是抢占失效的。如果被保护的共享资源需要在中断上下文访问(包括中断上半部和下半部[1]),就必须使用自旋锁。

     在ISR中都不能进行进程切换。因为ISR不属于任何进程,而切换只能发生在进程上下文中。虽然ISR在执行过程中要

    使用进程的系统堆栈,但那只是借用,堆栈并不属于isr,而是属于进程。  http://www.chinaunix.net/old_jh/4/902033.html

    通常32位Linux内核,进程地址空间划分0~3G为用户空间,3~4G为内核空间。内核空间中的内核代码、数据,为所有进程共享,由MMU映射在相同的物理内存地址。

     

      进程进入内核态后,内核代码所使用的栈并不是用户空间中的栈,而是内核空间的栈,进程的“内核栈”。

    [1]?怎么理解“中断运行在中断上下文,没有一个所谓的中断描述符来描述它,它不是操作系统调度的单位。一旦在中断上下文中睡眠,首先无法切换上下文(因为没有中断描述符,当前上下文的状态得不到保存),其次,没有人来唤醒它,因为它不是操作系统的调度单位。 ”

     

  • 相关阅读:
    个人网址收集
    使用 TListView 控件(2)
    C# 语法练习(14): 类[六] 事件
    如何在 "万一的 Delphi 博客" 回复自动格式化的着色代码?
    使用 TListView 控件(1)
    C# 语法练习(13): 类[五] 索引器
    使用 TListView 控件(4)
    C# 语法练习(11): 类[三] 构造函数、析构函数、base、this
    C# 语法练习(12): 类[四] 抽象类与抽象成员、密封类与密封成员
    使用 TListView 控件(3)
  • 原文地址:https://www.cnblogs.com/wenxuanguan/p/3897722.html
Copyright © 2020-2023  润新知