文章目录
以下内容为<<linux内核编程>>读书笔记
进程与程序
1. 进程是程序执行的基本单位,程序是有若干函数组成的可执行文件,而进程指的是特定程序的一个实例
2. 程序包括:文本段,数据段,栈,堆,文本段存放CPU所致型的指令;数据段存放进程操作的所有数据变量;栈存放自动变量和函数数据;堆存放动态内存分配的数据;
当进程创建时,子进程收到父进程的数据副本,包括数据空间,堆,栈和进程描述符。
以下为创建进程的实例:
#include <sys/types.h> #include <stdio.h> #include <sys/stat.h> #include <fcntl.h> int main(void) { int fd; int pid; pid = fork(); //创建进程 if(pid==0) { execle("/bin/ls", NULL); exit(2); } if(waitpid(pid) < 0) printf("wait error\n"); pid = fork(); if(pid==0) { fd=open("otc/otc.c", O_RDONLY); close(fd); } if(waitpid(pid)<0) printf("wait error\n"); return 0; }
这个程序定义了一个执行上下文。进程的上下文由PSW,寄存器,内存和文件中存储的值组成。而进程管理的特征存放在一个单独的数据结构:进程描述符 中
进程描述符
进程描述符:task_struct,内核采用循环双向链表task_list来采用存放所有进程描述符,并借助全局变量current来存放当前运行进程的task_struct的引用
以下是进程描述符必须记录的信息:
进程的属性,进程间的关系,进程的内存空间,文件管理,信号管理,进程的信任状,资源限制,与调度相关的字段
与进程属性相关的字段
1. state,用于记录进程的状态,在其执行生命周期内,其可能的值:TASK_RUNNING,TASK_INTERRUPTIBLE,TASK_UNINTERRUPTIBLE,TASK_ZOMBLE,TASK_STOPPED,TASK_DEAD
2. pid,每个进程都有一个唯一的进程标识符,类型为pid_t,其实为短整型
3. 标志,定义的是进程的特殊属性
4. binfmt,exit_code等
与调度相关的字段
多个进程共享一个CPU,调度程序为每个进程分配一个时间片和优先级来实现公平,高效的调度。时间片定义了一个进程被切换掉,运行另一个进程之前二允许运行的时间长度。进程的优先级则是一个数值,它定义了相对其他就绪进程而言,进程被允许执行的相对顺序。
prio,static_prio(nice值)
run_list:准备运行的进程队列,policy等等
进程间相互关系的字段
每一个进程都有一个创建它的父进程p,而p也可能有兄弟进程
1. real_parent,指向当前进程的父进程的进程描述符
2.parent:指向其父进程描述符的指针
3.children:指向当前进程 的子进程列表的struct
4.sibling:指向当ianjincheng的兄弟进程列表的struct
5.greoup_leader:每个进程组的组长的类型
与进程信任状相关的字段
1.uid和gid:uid存放创建改进成的用户的ID,gid是该进程所在进程组的组ID
2. euid和egid suid和sgid 等
与文件系统及地址空间相关的字段
进程总是通过执行打开,关闭,读,写文件按这样的任务与文件密切相关;
fs 字段保存一个指向文件系统信息的指针
files 保存一个指向进程的文件描述符表的指针
mm 指向与地址空间及内存管理相关的信息
进程的创建:系统调用fork(),vfork,clone()
fork函数
fork函数返回2次,一次是在父进程,一次是在子进程,如果在子进程中返回,将返回0,如果在父进程中返回,将返回子进程的PID。当fork函数调用时,该函数把包括该系统调用表索引表在内的一些必要信息放入适当的寄存器,系统调用表中存放系统调用的指针有处理器来决定将这些信息放入哪个寄存器中
fork函数调用的是do_fork函数
vfork函数
vfork的父进程已知阻塞,知道子进程调用exit()或exec()为止
clone函数把一个指向函数的指针和该函数的参数作为自己的参数
进程的生命周期
进程所处的第一个状态是TASK_INTERRUPTIBLE,这是在由do_fork()调用的copy_process()历程中创建进程时设置的,进程的第二个状态是TASK_RUNNING,这是在退出do_fork之前的设置的,最后一个状态是TASK_ZOMBIE,这是在do_exit期间被设置的
就绪态 -> 运行态 被调度程序选中
运行态 -> 就绪态 时间片用完,进程让出CPU
阻塞态 -> 就绪态 信号到来,或等待的资源变为可用的
运行态 -> 就绪态 进程睡眠或等待事件
进程的终止
主动终止进程:从main函数返回,调用exit
被动终止进程:进程可能收到自己不能处理的一个信号
当今成在内核态执行时可能产生一个异常
进程可能和搜到了SIGABRT信号或其他终止信号
当子进程先于父进程终止,则子进程编程一个僵尸进程,直到父进程调用wait或waitpid为止
当子进程在父进程之后终止,则该子进程将成为孤儿进程,知道init进程收养该子进程
wait函数的作用:获知进程消亡的信息,消除进程的所有痕迹