1.进程基本概念
程序和进程
- 某时刻进程的内容称为进程镜像(Process Image)
- 正文段 用户数据段 系统数据段 构成进程
进程的层次结构
Linux启动时创建一个Init进程,为每个tty终端生成一个管理进程,用户登录后启动一个shell进程,Init进程还负责收养孤儿进程
进程状态
- 运行态
- 就绪态
- 阻塞态
- 通过pid = fork()函数,在父进程pid为创建的子进程的ID,在子进程pid为 0
2.进程控制块
进程控制块PCB负责(PCB是进程存在和运行的唯一标志,常驻内存):
- 状态信息
- 链接信息
- 各种标识符
- 进程间通信信息
- 时间和定时器信息
- 调度信息
- 文件系统信息
- 虚拟内存信息
- 处理器环境信息
进程状态
- 就绪态(就绪态+运行态)
- 睡眠态
- 浅度睡眠 等待资源或者信号
- 深度睡眠 并不能被唤醒
- 暂停态
- SIGSTOP SIGTSTP SIGTTIN SIGTTOU 信号
- 僵死状态 进行释放大部分资源 但是PCB还存在
进程标识符
- 有一个最大标识符号,cat /proc/sys/kernel/pid_max
进程控制块
- 进程在内核中存在一个内核栈,该栈和一块指向PCB的小结构一起存放占用8KB左右
3.进程的组织方式
进程链表
哈希表 链表法解决冲突
就绪队列
等待队列 先唤醒前面的非互斥进程 再唤醒后面的互斥进程
4.进程调度
// TODO
5.进程创建
fork() 拷贝当前进程创建子进程,写时复制
exec() 负责读取可执行文件并在载入到进程空间
wait() 等待所有子进程结束
exit() 终止进程,进入僵死状态等待wait()收集信息并被杀死
errno为全局变量,系统调用失败可以读取errno中值来做判断
创建进程
fork或clone(线程)调用do_fork()函数
- 1.创建存放PCB和新进程的内核栈
- 2.拷贝父进程PCB内容到子进程
- 3.检查资源分配限制
- 4.建立子进程的资源
- 5.子进程处于TASK_UNINTERRUPTIBLE状态,确保不会马上运行
- 6.子进程获取有效的PID
- 7.更新子进程PCB
- 8.资源拷贝
- 9.子进程PCB插入进程链表
- 10.子进程PCB插入pidhash哈希表
- 11.子进程处于TASK_RUNNING状态,插入运行队列
- 12.父子进程共享剩余时间片
- 13.返回子进程的PID给父进程
调度程序优先调度子进程,因为防止父进程向地址空间写入,避免不必要的写时复制消耗
创建线程
内核线程和进程的差别:
- 1.内核线程执行内核函数,普通进程通过系统调用才能执行内核中的函数
- 2.内核线程只能运行在内核态,普通进程用户和内核态
- 3.内核线只能使用大于PAGE_OFFSET的地址空间,普通进程使用4GB的地址空间
特殊内核线程
- start_kernel()函数创建swap内核线程(idle process),该线程执行cpu_idle()函数,该函数执行hlt指令,该进程PCB叫init_task在很多链表中起链表头的作用,就绪队列为空时则选择该进程
- kernel_thread()函数创建kernel_init线程,该线程执行execve()函数装入Init(/sbin/init)来启动init 1号进程
网友评论