在互斥锁中,处理器(CPU)如何知道要解锁哪个进程?

Posted

技术标签:

【中文标题】在互斥锁中,处理器(CPU)如何知道要解锁哪个进程?【英文标题】:In mutex,how the processor(CPU) know which process to unlock? 【发布时间】:2017-02-05 04:03:14 【问题描述】:

据我所知,锁定互斥锁的进程是必须解锁互斥锁的进程。我的疑问是 处理器如何知道要解锁哪个进程?是否有任何数据结构可以将特定进程(内部)的 pid(或)某些内容保存在 waitque 中?所以,处理器只能解锁特定进程。

请给予答复..这个问题在我的一次采访中提出。

【问题讨论】:

您是否询问内核如何调度等待互斥锁的线程/进程以运行自主“测试和设置”CPU 命令来尝试获取互斥锁?我不相信哪个线程将首先获得互斥锁有任何保证,因此可能有多种功能实现。 【参考方案1】:

获得互斥锁的线程/进程是代码中唯一向前移动的线程/进程。稍后在该线程的代码中应该释放互斥锁。没有互斥锁的其他线程/进程将等待它,因此在 1 个正在运行的进程到达互斥锁释放之前,它们既不会获取它也不会释放它。

【讨论】:

【参考方案2】:

处理器如何知道要解锁哪个进程?

处理器什么都不知道;它只是盲目地执行已经提供给它的机器指令链。

另一方面,线程库经过精心设计,可以处理这类事情。此外,每个现代/多任务操作系统都包含一个线程调度程序,该线程调度程序在启动时加载到内存中,它管理哪些线程可以运行以及何时运行。它与线程库一起工作以正确处理锁定/解锁问题。

所以问题就变成了:当互斥锁被解锁时,操作系统软件如何知道接下来要唤醒哪个线程?

当然实际的实现会随着操作系统的不同而不同,但是从概念上你可以想象每个互斥对象都包含一个链表,当一个线程试图锁定一个已经被锁定的互斥对象时,线程会将自己添加到链表,然后告诉调度程序让它(线程)进入睡眠状态。

稍后,当互斥锁被解锁时,解锁例程将第一个休眠线程(如果有)从链表中弹出,将互斥锁的所有权重新分配给该线程,然后要求调度程序唤醒该线程尽快线程。

(警告:现实世界的实现可能会比这更复杂一些,因为它需要小心避免竞争条件并最大限度地提高性能,但我认为这让您了解如何完成它。请注意,在此示例实现中,线程将以先到先服务的方式获取互斥锁,即以它们调用 lock() 的相同顺序,但在许多实际实现中,不能保证该顺序,因此你不应该依赖它)

【讨论】:

感谢您的回复...我明白您所说的...当您提到“将互斥锁的所有权重新分配给该线程”时,您的实际意思是什么? @杰里米弗里斯纳 @sravanthi 一次只有一个线程持有互斥锁;持有互斥锁的线程被称为互斥锁的所有者。当 lock() 在线程中返回时,可以保证该线程是互斥锁的所有者。因此,如果线程 B 在 lock() 内部等待,因为线程 A 是互斥锁的所有者,并且线程 A 对互斥锁调用 unlock(),此时线程 B 将成为互斥锁的所有者,线程 B 的 lock() call 将返回,以便线程 B 可以恢复执行。

以上是关于在互斥锁中,处理器(CPU)如何知道要解锁哪个进程?的主要内容,如果未能解决你的问题,请参考以下文章

Linux 有问必答:如何知道进程运行在哪个 CPU 内核上?

信号量,互斥锁,自旋锁

Linux 进程与线程四(加锁--解锁)

三星手机root之前要解锁的工具不能用 CROM Service 停止服务怎麼办

[转帖]判断Linux进程在哪个CPU核运行的方法

编译器说数据不能在线程之间安全地共享,即使数据包装在互斥锁中