据我所知,多线程上下文切换是由操作系统抢占式发起的,从线程的角度来说是透明的。通常,当上下文切换时,操作系统会保存所有寄存器值,并在稍后切换回该线程时恢复它们。这包括该线程的堆栈指针。
但考虑一下假设的无寄存器机器。在这里,我可以使用内存中的固定地址来存储堆栈指针。但在这里,当上下文切换时,不保证堆栈指针被保留。另一个线程将其堆栈指针存储在同一地址中。由于它是一个全局变量,它会破坏同一线程中所有其他进程的堆栈指针。如何避免这种情况?如何存储堆栈指针而不必需要寄存器,但又在上下文切换后保持堆栈指针有效?
我问这个问题是因为,由于每台计算机都相当于基本图灵机,并且基本图灵机不包含寄存器,这应该以某种方式可行。我想了一会儿,却想不出什么办法。
编辑: 正如 @JérômeRichard 在评论中提到的,所有现代处理器都有寄存器,并且它们的 ISA 依赖于它们。因此,如果没有寄存器,内存复制也是不可能的。因此,在这里我将定义一个简单的架构以供论证之用。
它是一台具有 2^x 个可寻址单元的机器,每个单元都有一个唯一的 x 位地址。为了简单起见,假设没有虚拟内存的概念,并且整个地址空间直接映射到物理内存。因此,不需要申请内存,进程可以自由使用其整个x位地址空间。让操作系统存在于该地址空间之外并且不干扰用户进程。
此外,机器上仅运行一个用户进程。但它可以多线程。所有线程共享相同的地址空间。但它们都可以独立执行不同的指令和不同的数据。同样,为了简单起见,指令指针的切换由操作系统管理。
该处理器的 ISA 能够在给定地址的内存任何部分上读取、写入、复制数据。它还可以对数据进行任何算术、逻辑、位操作操作。让我省略所有其他浮点和向量指令。
当我们有一个单线程运行时,我们可以固定一些全局地址并存储当前函数的数据(例如帧指针和返回地址)并使用它们。现在的挑战是跨上下文切换存储和恢复线程特定的数据。假设该操作系统进行抢占式上下文切换。
As I know, multi-thread context switching is pre-emptive initiated by the OS, transparent from the perspective of thread. Generally, when context switching, OS saves all the register values and restores them later switching back to that thread. This includes stack-pointer of that thread.
But consider a hypothetical register-less machine. In this, I can use a fixed address in memory to store the stack-pointer. But here, when the context-switches, stack-pointer is not guaranteed to be preserved. The other thread stores its stack-pointer in the same address. Since it is a global variable, it will corrupt stack-pointer of all other process in the same thread. How to avoid this? How can I store stack-pointers without necessarily needing registers, but also keeping stack-pointer valid after a context-switch?
I'm asking this because, since every computer is equivalent to basic Turing machine, and basic Turing machine does not contain registers this should be somehow doable. I thought about it for some time now, and I was unable to come up with anything.
EDIT: As @JérômeRichard mentioned in comments, all modern processors have registers, and their ISAs are dependent on them. So even memory copying is not possible in them without registers. So here I am going to define a simple architecture for argument purposes.
It is a machine with 2^x addressable units, with each of them having a unique x-bit address. For simplicity, assume there is no concept of virtual memory, and entire address space is mapped directly to physical memory. So, there is no need for requesting memory, process can use its entire x-bit address space freely. Let OS be present outside this address-space and not interfere with user-process.
Also, there is only one user-process running on the machine. But it can multiple threads. All threads share same address space. But they all can independently execute different instructions and on different data. Again, for simplicity, switching of instruction pointer is managed by the OS.
This processor's ISA is capable of reading, writing, copying data on any part of memory given their address. It can also do any arithmetic, logic, bit-manip operations on the data. Let me leave out all other floating-point and vector instructions.
When we have a single thread running, we can fix some global address and store the current function's data like frame pointer and return address and use them. Now, the challenge is to store and restore thread-specific data like these across context switches. Assume this OS does pre-emptive context switches.
发布评论