我试图了解操作系统如何确定哪个线程是当前线程(例如,当线程调用gettid()
或时GetCurrentThreadId()
)。由于进程地址空间在所有线程之间共享,因此无法选择保留线程 ID。它必须是每个线程独有的东西(即存储在其上下文中)。如果我是一名操作系统开发人员,我会将其存储在一些仅在内核模式下可读的内部 CPU 寄存器中。我用谷歌搜索了很多,但没有发现任何类似的问题(好像它非常明显)。
那么它是如何在 Linux 或 Windows 等真实操作系统中实现的呢?
我试图了解操作系统如何确定哪个线程是当前线程(例如,当线程调用gettid()
或时GetCurrentThreadId()
)。由于进程地址空间在所有线程之间共享,因此无法选择保留线程 ID。它必须是每个线程独有的东西(即存储在其上下文中)。如果我是一名操作系统开发人员,我会将其存储在一些仅在内核模式下可读的内部 CPU 寄存器中。我用谷歌搜索了很多,但没有发现任何类似的问题(好像它非常明显)。
那么它是如何在 Linux 或 Windows 等真实操作系统中实现的呢?
您的问题的答案完全是系统特定的。然而,大多数处理器对线程一无所知。它们只支持进程。线程通常由创建的共享相同地址空间的单独进程实现。
当您执行系统服务调用以获取线程 ID 时,它将以与系统服务相同的通用方式实现以获取进程 ID。想象一下获取进程 ID 函数如何在不支持线程的系统中工作。为了简单起见,让我们假设一个处理器。
您将拥有某种数据结构来表示当前进程,并且内核将拥有一些识别当前进程的方法(例如,内核地址空间中指向该进程的指针)。在某些处理器上,有一个当前任务寄存器指向处理器规范定义的结构。操作系统通常可以将自己的数据添加到此结构的末尾。
所以现在我想升级这个操作系统来支持线程。为此,我必须有一个描述线程的数据结构。在那个结构中,我有一个指向定义过程的结构的指针。
然后获取线程 ID 的工作方式与之前获取进程 ID 的工作方式相同。但是现在获取进程 ID 有一个额外的步骤,我必须将线程转换为进程以获取其 id(甚至可能包含在线程块中)。
我相信这已经在这个问题中得到了很好的解释:内核如何区分线程和进程
如果您想了解更多信息,您还可以 google内核任务结构,并查看在用户空间中运行的每种类型的进程存储了哪些信息
您正在寻找线程控制块(TCB)。
它是一种保存有关线程信息的数据结构。
可以在此处找到有关该主题的轻型阅读材料: https ://www.cs.duke.edu/courses/fall09/cps110/slides/threads2.3.ppt
但是,如果您对操作系统感兴趣,我建议您获取 Andrew S. Tanenbaum 的 Modern Operating Systems 的副本。
第 2 章第 2.2 节主题:
在用户空间中实现线程 - “当在用户空间中管理线程时,每个进程都需要自己的私有线程表来跟踪该进程中的线程。”
在内核中实现线程 - “内核有一个线程表,用于跟踪系统中的所有线程。”
只是一个编辑,您可能还想阅读“调度”。一般来说,您可以说内核决定哪个线程/进程应该使用 CPU。因此内核知道哪个线程/进程进行了系统调用。我不会详细介绍,因为这取决于我们正在谈论的操作系统。