1. 进程和虚拟内存简介
程序本来是存储在磁盘的,当我们需要执行它的时候,先把它读取到内存当中,再然后放入到寄存器中,最后让cpu执行程序,这个时候程序就变成了一个进程.每个进程直接肯定都拥有自己独有的一份管理自己的单独的任务结果 .而这个任务结果就是我们今天的PCB. 每个进程运行的时候都会拿到4G的虚拟内存.其中3G是交给用户的,然后剩下的1G内存存储内核的东西了.我们的PCB其实就存储在1G的内核系统空间里面. 他其实就是一个task_struct结构体.里面存储这进程的所有信息。
先思考一个问题:每一个进程都需要4G的虚拟内存,而你的物理内存就那么点,而我们的计算机当中有成千上万的进程,那么这些进程都存有自己的PCB,物理内存其实就只有那么一点,那么这些巨大数量的PCB是怎么存储的呢? 虚拟内存有什么特殊的作用呢?详见虚拟内存和物理内存的区别和联系文档。下图简要示意:
2. task_truct结构体
struct task_struct {
volatile long state; //说明了该进程是否可以执行,还是可中断等信息
unsigned long flags; //Flage 是进程号,在调用fork()时给出
int sigpending; //进程上是否有待处理的信号
mm_segment_t addr_limit; //进程地址空间,区分内核进程与普通进程在内存存放的位置不同
//0-0xBFFFFFFF for user-thead
//0-0xFFFFFFFF for kernel-thread
//调度标志,表示该进程是否需要重新调度,若非0,则当从内核态返回到用户态,会发生调度
volatile long need_resched;
int lock_depth; //锁深度
longnice; //进程的基本时间片
//进程的调度策略,有三种,实时进程:SCHED_FIFO,SCHED_RR,分时进程:SCHED_OTHER
unsigned long policy;
struct mm_struct *mm; //进程内存管理信息
int processor;
//若进程不在任何CPU上运行, cpus_runnable 的值是0,否则是1这个值在运行队列被锁时更新
unsigned long cpus_runnable, cpus_allowed;
struct list_head run_list; //指向运行队列的指针
unsigned long sleep_time; //进程的睡眠时间
//用于将系统中所有的进程连成一个双向循环链表,其根是init_task
struct task_struct *next_task, *prev_task;
struct mm_struct *active_mm;
struct list_head local_pages; //指向本地页面
unsigned int allocation_order, nr_local_pages;
struct linux_binfmt *binfmt; //进程所运行的可执行文件的格式
int exit_code, exit_signal;
int pdeath_signal; //父进程终止时向子进程发送的信号
unsigned long personality;
//Linux可以运行由其他UNIX操作系统生成的符合iBCS2标准的程序
int did_exec:1;
pid_t pid; //进程