第三章-进程

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号进程

你可能感兴趣的:(第三章-进程)