“互斥锁”到底有什么作用?

2024-02-07

您可以在此链接中看到一个有趣的表格。http://norvig.com/21-days.html#answers http://norvig.com/21-days.html#answers

该表描述,
互斥锁/解锁 25 nanosec
从主存中获取 100 nanosec

Nanosec?
我很惊讶因为mutex lockfetch data from memory。如果是这样,什么mutex lock到底是怎么做的?什么是Mutex lock意思是在桌子上?


假设十个人必须共用一支笔(也许他们在一家非常缺钱的公司工作)。由于他们必须用笔写很长的文档,但写文档的大部分工作只是想说什么,所以他们同意每个人都可以用笔写文档的一句话,然后必须使其可供小组的其他成员使用。

现在我们有一个问题:如果两个人都想完了下一句话,并且都想立即使用笔怎么办?只能说两个人都可以抢到笔,但是这是一支很脆弱的旧笔,如果两个人抢的话它就会断掉。相反,我们在笔周围画一条粉笔线。首先你把手放在粉笔线上,then你抓住笔。如果一个人的手位于粉笔线内,则其他人不得将手放入粉笔线内。如果两个人试图同时把手伸过粉笔线,根据这些规则,只有其中一个人会先进入粉笔线,所以另一个人必须缩回手并保持在粉笔线外,直到笔又可用了。

让我们将其与互斥体联系起来。互斥锁是一种在短时间内保护共享资源(笔)的方法,称为临界区(写一篇文档的一句话的时间)。每当您想使用该资源时,您同意致电mutex_lock首先(将手放在粉笔线内)。每当您使用完资源后,您同意致电mutex_unlock(将手从粉笔线区域移开)。

现在介绍互斥体是如何实现的。互斥体通常使用共享内存来实现。有一些共享的不透明数据对象,称为互斥体,并且mutex_lock and mutex_unlock函数都采用指向其中之一的指针。这mutex_lock函数使用原子测试和设置或加载链接/存储条件指令序列(在 x86 上,xhcg经常使用),或者“获取互斥体”——设置互斥体对象的内容以向其他线程指示关键部分已锁定——或者必须等待。最终,线程获得互斥锁,在临界区内完成工作,并调用mutex_unlock。该函数设置互斥体内部的数据以将其标记为可用,并可能唤醒一直试图获取互斥体的睡眠线程(这取决于互斥体的实现 - 的一些实现mutex_lock只是紧紧地旋转着xchg直到互斥锁可用,所以不需要mutex_unlock通知任何人)。

为什么锁定互斥体比访问内存更快?简而言之,就是缓存。 CPU有一个高速缓存,可以非常快速地访问,因此xchg只要处理器可以确保没有其他处理器访问该数据,操作就不需要一直到内存。但是 x86 有一个“拥有”高速缓存行的概念 - 如果处理器 0 拥有高速缓存行,则任何其他想要使用该高速缓存行中的数据的处理器都必须经过处理器 0。这样,就不需要xhcg查看缓存之外的任何数据的操作,并且缓存访问往往非常快,因此获取无竞争的互斥体比内存访问更快。

不过,最后一段有一个警告:速度优势仅适用于无争议的互斥锁。如果两个线程尝试同时锁定同一个互斥锁,则运行这些线程的处理器必须进行通信并处理相关缓存行的所有权,这会大大减慢互斥锁的获取速度。此外,两个线程之一必须等待另一个线程执行临界区中的代码,然后释放互斥体,这进一步减慢了其中一个线程的互斥体获取速度。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

“互斥锁”到底有什么作用? 的相关文章

  • 如何在 Ada 中直接访问内存地址?

    所以我是 Ada 的新手 我正在尝试在其中编写内核 但我似乎找不到任何关于如何正确执行此操作的好信息 在 C 语言中 我会这样写 unsigned char videoram char 0xB8000 videoram 0 65 直接访问视
  • 为什么需要锁来实现 readonly int 属性?

    我是线程新手 我遇到了一个自定义线程池实现示例blog http ferruh mavituna com net multithreading ve basit bir threadpool implementasyonu oku 我只粘贴
  • 如何在 C# 中编写条件锁?

    问题是我一直在使用锁语句 http msdn microsoft com en us library c5kehkcz aspx为了保护我的代码的关键部分 但现在 我意识到我可以允许在满足某些条件的情况下并发执行该关键代码 有没有办法调节锁
  • 用于查找谁锁定文件的命令行工具

    我想知道谁正在锁定文件 win32 我知道关于谁锁我 http www dr hoiby com WhoLockMe 但我想要一个命令行工具或多或少做同样的事情 我也看了这个问题 https stackoverflow com questi
  • “忙等待”与“睡眠”的权衡是什么?

    这是我之前问题的延伸 unix linux 套接字中的阻塞模式如何工作 https stackoverflow com questions 1107391 how does blocking mode in unix linux socke
  • 自旋锁在单处理器单核架构中有用吗?

    我对自旋锁的功能感到困惑 自旋锁用于阻止进程重新调度 然而 在只有一个核心的机器上 使用自旋锁有用吗 防止上下文切换 您的观察结果很好 在单处理器系统上 旋转等待资源是没有意义的 因为您最好尽早切换线程 互斥体和信号量正是这样做的 在多处理
  • 如何在Linux内核中启用CONFIG_PREEMPT选项?

    我是 Linux 内核编程的新手 尝试在 x86 64 上使用旧内核 Linux 2 6 32 我想启用其中的 CONFIG PREEMPT 选项 但找不到有关如何执行此操作的信息 我可以使用我的首选选项编译新内核 但不知道在这种情况下我需
  • 杀死 OpenCL 内核

    有没有办法通过 OpenCL API 终止正在运行的 OpenCL 内核 我在规范中没有找到任何内容 我能想到的唯一解决方案是 1 定期检查内核中主机希望内核停止时写入的标志 或 2 在单独的进程中运行内核并终止整个进程 我认为这两个都不是
  • Linux 内核:Spinlock SMP:为​​什么 spin_lock_irq SMP 版本中有 preempt_disable()?

    Linux内核中的原始代码是 static inline void raw spin lock irq raw spinlock t lock local irq disable preempt disable spin acquire l
  • 编译错误:linux/module.h:没有这样的文件或目录

    我写了一个简单的模块 define KERNEL define MODULE include
  • 如何使用 GWT 检测操作系统?

    Basically what I want to know is to find out if my GWT application is running on a MacOS or any other operating system t
  • 全局键盘挂钩的合法用途是什么?

    除了仅应由操作系统提供的应用程序启动快捷方式之外 Windows 键盘挂钩等东西的合法用途是什么 在我看来 我们只在键盘记录器之类的事情上遇到问题 因为操作系统提供了钩子来执行除操作系统内核本身之外的任何情况下任何人都不允许执行的操作 编辑
  • 每个进程是否都存在内核堆栈?

    每个用户空间进程是否都存在一个内核堆栈和一个用户空间堆栈 如果两个堆栈都存在 那么每个用户空间进程应该有 2 个堆栈指针 对吗 在 Linux 中 每个任务 用户空间或内核线程 都有一个 8kb 或 4kb 的内核堆栈 具体取决于内核配置
  • “do { ... } while (0)”在内核代码中到底做了什么? [复制]

    这个问题在这里已经有答案了 可能的重复 当我们定义宏时 do while 0 有什么用 https stackoverflow com questions 923822 whats the use of do while0 when we
  • 如何查找或计算Linux进程的页表大小和其他内核占用?

    我怎样才能知道 Linux 进程页表有多大 以及任何其他可变大小的进程统计 如果您真的对页表感兴趣 请执行以下操作 cat proc meminfo grep PageTables PageTables 24496 kB
  • 为什么使用Python的os模块方法而不是直接执行shell命令?

    我试图了解使用Python的库函数执行特定于操作系统的任务 例如创建文件 目录 更改文件属性等 背后的动机是什么 而不是仅仅通过执行这些命令os system or subprocess call 例如 我为什么要使用os chmod而不是
  • 尝试映射大页面 (1GB) 时 mmap 失败

    我做了什么 使用 root 启用大页 我的系统支持 1MB 大页 echo 20 gt proc sys vm nr hugepages 将大页文件系统挂载到 mnt hugepages mount t hugetlbfs nodev mn
  • 当IRQL下降时,Windows中如何触发软件中断?

    我知道对于硬件中断 当 KeAcquireInterruptSpinLock 调用 KeLowerIrql 时 HAL 会调整 LAPIC 中的中断掩码 这将允许自动服务排队的中断 可能在 IRR 中 但是对于软件中断 例如 ntdll d
  • Azure:列出操作系统映像

    我是 Windows azure 新手 我看过这个文档 http msdn microsoft com en us library windowsazure jj157191 aspx 对我来说它有效 在画廊上列出图像 https mana
  • Linux内核页表更新

    在linux x86 中分页 每个进程都有它自己的页面目录 页表遍历从 CR3 指向的页目录开始 每个进程共享内核页目录内容 假设三个句子是正确的 假设某个进程进入内核 模式并更新他的内核页目录内容 地址映射 访问 权利等 问题 由于内核地

随机推荐

  • jQuery / JavaScript 中的自定义滚动条数学

    我目前正在开发一个项目 该项目使用自定义滚动插件 由我编写 来允许元素在触摸设备以及桌面浏览器中滚动 一切都工作正常 包括 iOS 的速度和减速度 然而 剩下的唯一问题是当用户滚动时计算滚动条的顶部 或左侧 位置 我用以下公式计算了滚动条的
  • 在我的 Express.js Jest 测试中找不到内存泄漏

    我现在花了一些时间尝试在 Jest 测试中查找内存泄漏 尽管我已经成功解决了一些问题 但仍然有相当多的内存在测试套件之间泄漏 具体来说 当我npm test 所有测试套件 我得到以下输出 PASS src suite1 test ts 71
  • iPhone 消息应用程序中的上滑菜单是如何实现的?

    在我的 iPhone iOS 8 0 2 上的消息应用程序中 当您撰写消息并单击相机图标插入图像时 底部会出现一个 向上滑动 菜单 它包含一些按钮 以及我可以插入到消息中的最近拍摄的照片 这个菜单叫什么名字 已经可以通过本地课程获得了吗 图
  • 无法搜索联系人

    所以我制作了一个静态联系人列表 并尝试添加搜索栏 但是我无法使用搜索栏搜索联系人 当我单击搜索栏时 它会打开但随后关闭 键盘会弹出一会儿 然后就会关闭 这个想法是使搜索具有预测性 因此当输入名称时 它将根据数据库中的名称列出已关闭的名称 有
  • 删除 JSON 元素

    我想从 JSON 中删除 JSON 元素或一整行 我有以下 JSON 字符串 result FirstName Test1 LastName User FirstName user LastName user FirstName Ropbe
  • Haskell:映射函数应用

    我在 Haskell 中进行的部分计算会产生映射的函数列表Float to Float 我想对所有这些函数应用一个参数 如下所示 x Float functions Float gt Float map f gt f x functions
  • 如何检查空结构?

    我定义了一个结构体 type Session struct playerId string beehive string timestamp time Time 有时我给它分配一个空会话 因为 nil 是不可能的 session Sessi
  • matlab 脚本中是否使用了某些 matlab 例程?

    我正在运行一个大的 m 文件 该文件不是我自己编写的 并且取决于某些子函数 我想知道所有嵌套函数中的任何位置是否使用了特定函数 在我的例子中是函数 eig m 用于计算特征值 有没有快速的方法来做到这一点 亲切的问候 科恩 您可以使用半文档
  • 如何编写 GraphQL 查询以从 github 检索所有工作流程/运行

    如何编写 GraphQL 查询以从 github 检索所有工作流程 运行 我尝试下面的查询来获取节点 id organization login abc repositories first 100 nodes id name 和下面的查询
  • Microsoft Teams:获取用户的时区?

    我正在为 MS Teams 开发一个机器人 我希望了解用户的时区 以便在适当的时间 例如 不是在半夜 传递消息 我没有在机器人框架 REST API 中找到合适的东西 虽然我们收到的消息包含 clientInfo country 属性 这是
  • 枚举另一个会话上用户桌面的 Windows

    我有一个简单的问题让我发疯 我有一个用 C 编写的 Windows 服务 它应该在 XP Vista 和 7 上运行 并且能够枚举当前用户桌面的窗口 如果有 以进行监控 So far 我用过EnumDesktopWindows通过IntPt
  • XmlSerializer序列化接口的通用列表

    我正在尝试使用 XmlSerializer 来保存 List T 其中 T 是一个接口 序列化器不喜欢接口 我很好奇是否有一种简单的方法可以使用 XmlSerializer 轻松序列化异构对象列表 这就是我想要的 public interf
  • 使用 ColdFusion 对单点登录数据进行签名

    对于这篇文章的长度 我提前表示歉意 我对这个问题的了解还不够 无法正确确定具体问题实际上是什么 但无论如何 我们一直在使用 Leigh 提供的步骤和建议来调用我们的会员 API 来查询有关我们会员的信息 加入日期 会员类型等 here ht
  • 使用 Python 的 select 模块检查是否有更多数据可以从文件描述符中读取

    我有一个程序 它在线程中创建一个子进程 以便线程可以不断检查特定的输出条件 来自 stdout 或 stderr 并调用适当的回调 而程序的其余部分继续 这是该代码的精简版本 import select import subprocess
  • Toast 通知失败,模拟器

    我在这里使用 toast 通知示例 http code msdn microsoft com windowsapps Toast notifications sample 52eeba29 http code msdn microsoft
  • 将行添加到 WPF 数据网格,其中列直到运行时才知道

    我正在尝试将数据添加到数据网格 事实上 任何在网格中呈现数据的控件都可以 但列 名称和数字 直到运行时才知道 我知道如何创建的专栏 例如 DataGridTextColumn textColumn new DataGridTextColum
  • Eclipse Helios 忽略断点

    Eclipse 现在快把我逼疯了 这可能是一件微不足道的事情 但我就是不明白 每当我想添加断点时 常规图标都会在编辑器和断点视图中被划掉 正如您可能已经猜到的那样 这严格来说并不是一个图形问题 调试时断点会被忽略 断点的属性也没有帮助 任何
  • MongoDB:使用不同的值进行更新和插入

    一些背景信息 我为每个用户都有一个文档 其中包含一个数组 其中包含与用户相关的最新 20 个事件 由于 MongoDB 没有此功能 限制文档内的数组 我将推送我的事件并弹出最新的事件 我的问题 初始化文档 又名用空值填充数组 我想原子地 创
  • JDODetachedFieldAccessException:您刚刚尝试访问字段“附件”,但在分离对象时该字段尚未分离

    实体类 public class CustomerSurvey implements Serializable Id GeneratedValue strategy GenerationType SEQUENCE generator CUS
  • “互斥锁”到底有什么作用?

    您可以在此链接中看到一个有趣的表格 http norvig com 21 days html answers http norvig com 21 days html answers 该表描述 互斥锁 解锁 25 nanosec 从主存中获