Linux - 进程-线程-内核线程概念区分
父进程与子进程
父子进程虚拟内存空间
- 通过
vfork/clone系统调用创建出的子进程(线程)共享父进程的虚拟内存空间:即直接将父进程的虚拟内存空间结构体「struct mm_struct」的地址赋值给子进程中的虚拟内存空间结构体指针,并增加父进程虚拟内存空间结构体的引用计数;即子进程不含有「struct mm_struct」的内存 - 通过
fork系统调用创建出的子进程,则将父进程的虚拟内存空间以及相关页表拷贝到拷贝到子进程的「struct mm_struct」中,即子进程含有自己的「struct mm_struct」结构内存 -> 此时子进程虚拟内存对应的物理内存应该是与父进程相同的!!!❌ -> 共享代码段,但是数据段不共享,可以采取写时复制技术
- 通过
子进程共享了父进程的虚拟内存空间,这样子进程就变成了我们熟悉的线程,是否共享地址空间几乎是进程和线程之间的本质区别。Linux 内核并不区别对待它们,线程对于内核来说仅仅是一个共享特定资源的进程而已
「内核线程」和「用户态线程」的区别就是内核线程没有相关的内存描述符 mm_struct ,内核线程对应的 task_struct 结构中的 mm 域指向 NULL,所以内核线程之间调度是不涉及地址空间切换的。
当一个内核线程被调度时,它会发现自己的虚拟地址空间为 Null,虽然它不会访问用户态的内存,但是它会访问内核内存,聪明的内核会将调度之前的上一个用户态进程的虚拟内存空间 mm_struct 直接赋值给内核线程,因为内核线程不会访问用户空间的内存,它仅仅只会访问内核空间的内存,所以直接复用上一个用户态进程的虚拟地址空间就可以避免为内核线程分配 mm_struct 和相关页表的开销,以及避免内核线程之间调度时地址空间的切换开销。
内核线程 🆚 用户进程/线程的内核态
用户进程处于用户态时看到用户空间;陷入内核时要能看到内核空间、同时也能看到内核空间。
因此进程的页表中应该含有内核空间映射信息?或者直接使用一个固定的映射信息。
Linux - 进程-线程-内核线程概念区分
http://example.com/2024/09/09/操作系统/Linux - 进程-线程-内核线程概念区分/