c++ - 当线程等待互斥锁时,cpu会做什么

标签 c++ multithreading

我对线程等待互斥体期间 cpu 的行为感到好奇。现在我可以想象两种可能性:

  1. CPU 停留在当前线程上并不断检查互斥体是否已解锁。
  2. CPU 将暂时切换到另一个线程(或进程),然后切换回原始线程并检查临时值。 哪个是正确的还是STL以另一种方式实现?

最佳答案

要理解这一点,您首先需要了解线程和 CPU 核心之间的区别。线程是一个抽象的东西,一种数据结构,用于表示一些要执行的操作序列。操作系统将线程分配给 CPU 核心,然后这些核心执行这些操作。操作系统(以及硬件)还可以随时中断此执行(尽管不是在单个指令的中间),保存此类线程的状态,挂起它,并将其他线程分配给该核心。这也称为上下文切换。操作系统有时也会在所谓的系统调用(当程序调用某些操作系统的功能时,例如请求访问磁盘、网络等)上执行此操作。这很重要,因为互斥体在幕后利用了一些系统调用。

那么当线程尝试访问锁定的互斥体时会发生什么?首先,没有定期检查。虽然有可能,但这会浪费 CPU 周期,而且任何严肃的操作系统都不太可能这样做。实际发生的情况是每个互斥体内部都有一个关联的队列。当它被锁定时,操作系统会将当前线程添加到该队列中并挂起它。之后,操作系统会将其他线程分配给该 cpu 核心(如果可用)。

现在,如果一个互斥体被锁定,那么就有一个线程实际锁定了该互斥体。我们将该线程称为所有者。该线程没有挂起,并且它执行一些工作。当它完成正在做的事情时,它必须解锁互斥体(这也是一个系统调用),否则那些挂起的线程将永远不会恢复。当这种情况(即解锁)发生时,操作系统将查看关联的队列,并从中选择一个线程(哪个是实现细节,通常是某个优先级队列)。这个新选择的线程将成为互斥体的新所有者,操作系统将恢复它,这意味着安排线程执行。安排时间,因为此时所有核心可能都很忙。

请注意,这是该主题的简要概述。还有很多其他的事情和优化正在发挥作用,例如 futexes以及如何在没有互斥体的情况下实际实现线程安全(或更确切地说是核心安全)代码(这些不是硬件功能,互斥体是在操作系统中实现的)。但事情或多或少就是这样。

关于c++ - 当线程等待互斥锁时,cpu会做什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71425393/

相关文章:

c# - 我的线程数组有问题

c++ - Android 服务器最佳实践

c++ - 在 C++ 中从数组函数设置一个数组

java - 在单独的线程中停止可运行的

Ruby - 主线程退出时不要终止进程

python - 使用 Python Turtle 进行多线程处理

c - fork 和现有线程?

c++ - 如何判断哪些参数是必需的,哪些不是? (视觉 C++)

c++ - 如何检索或打印 "Catch"信息记录缓冲区?

c++ - 为什么我的程序中的第二个 while 循环在它前面有一个 while 循环时不起作用?