task_struct剖析

[TOC]

Linux 中task_struct和文件系统的关系。

mm指向进程的虚拟内存,files指向一个数组,装载进程打开文件的指针。ffiles【0】标准输入,files【1】标准输出,files【2】标准错误输出。如果需要其他资源,比如打开一个文件进行读写,就进行一个系统调用,让内核把文件打开,放到files【4】。

对于一个进程的线程来说,他们的mm和files都指向同一个区域。

fork会创建一个task_struct的结构体,代表子进程。并为他分配进程所需要的信息。由于fork采用写时复制,在子进程没开始写的时候,子进程的task中指向内存资源的指针的指向和父进程相同。当开始写的时候,操作系统才copy资源给子进程,然后将子进程的task_struct的指针重新指向新的内存资源

在fork之后exec之前两个进程用的是相同的物理空间(内存区),子进程的代码段、数据段、堆栈都是指向父进程的物理空间,也就是说,两者的虚拟空间不同,但其对应的物理空间是同一个。当父子进程中有更改相应段的行为发生时,再为子进程相应的段分配物理空间,如果不是因为exec,内核会给子进程的数据段、堆栈段分配相应的物理空间(至此两者有各自的进程空间,互不影响),而代码段继续共享父进程的物理空间(两者的代码完全相同)。而如果是因为exec,由于两者执行的代码不同,子进程的代码段也会分配单独的物理空间。

task_struct是Linux内核的一种数据结构,它会被装载到RAM中并且包含着进程的信息。每个进程都把它的信息放在 task_struct 这个数据结构体,task_struct 包含了这些内容:

(1)标示符 : 描述本进程的唯一标识符,用来区别其他进程。

(2)状态 :任务状态,退出代码,退出信号等。
(3)优先级 :相对于其他进程的优先级。
(4)程序计数器:程序中即将被执行的下一条指令的地址。
(5)内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。
(6)上下文数据:进程执行时处理器的寄存器中的数据。
(7) I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
(8) 记账信息:可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。

在内核进程运行的时候,有current 宏对应目前进程task_struct结构

image-20210907104329851

Linux进程主要数据结构之间的关系。

如图:

img

一个进程文件位置是有fs_struct描述的,进程打开的文件是有files_struct描述的,具体打开的文件描述符是有file控制的。