我最近了解到 fork 即使在寄存器上也应用 COW(写时复制)。
我玩了一个简单的玩具盒来验证:
(gdb) info inferiors
Num Description Connection Executable
* 1 process 59316 1 (native) /home/Drew/mycode/a.out
2 process 59386 1 (native) /home/Drew/mycode/a.out
(gdb) print( $rdi )
$1 = 18874385
(gdb) set $rdi=42
(gdb) print( $rdi )
$2 = 42
(gdb) inferior 2
[Switching to inferior 2 [process 59386] (/home/Drew/mycode/a.out)]
[Switching to thread 2.1 (process 59386)]
#0 0x00002aaaab090291 in fork () from /lib64/libc.so.6
(gdb) print( $rdi )
$3 = 18874385
正如你们所见,修改父进程中的 rdi 不会干扰子进程。
我想知道这是怎么做到的?现代CPU是否专门为多进程提供多个相同的寄存器?
编辑:
感谢各位朋友的评论。我会在这里集中回答评论中的问题,希望它有助于澄清。
我使用的参考是本讲义。
我通常想弄清楚:
提供抢占式多任务处理的系统提供CPU虚拟化。这使得每个线程的行为就像它自己有一个 CPU(及其寄存器)一样。更具体地说,这允许线程使用寄存器,而不必担心它们在操作过程中被另一个线程(同一进程或不同进程的)更改。
无论线程如何创建,情况都是如此,因此包括由
fork
创建的线程。系统如何实现这一点并不重要。但它确保对一个线程中的 rdi
或指令指针的任何更改不会在另一个线程中看到。