Linux进程&线程
● 认识冯诺依曼体系结构
● 简单认识操作系统
● 进程概念(进程状态、优先级、环境变量、进程调度)
● 进程控制(僵尸进程、孤儿进程)
● 多线程
● 多进程 VS 多线程
● 进程地址空间
1. 冯诺依曼体系结构:现代计算机硬件体系结构
- 输入设备:键盘
- 输出设备:显示器
- 存储器:内存条
- 运算器:中央处理器(CPU)
- 控制器
硬件结构决定了软件行为/所有设备都是围绕存储器工作的
2. 操作系统:内核+应用
- 功能:管理计算机软硬件资源
- 定位:搞管理的软件
- 目的:让计算机更加好用
如何管理:先描述,再组织
库函数与系统调用接口的关系:
- 库函数封装了系统调用的接口;上下级的调用关系
PS:man手册:
1号 命令手册
2号 查看系统调用的接口
3号 显示库函数手册
3.进程
● 站在操作系统的角度上,进程就是一个运行中的程序描述——PCB(进程控制块)
● LINUX下这个pcb实际上是一个结构体,struct task_strust{....}
进程如何描述一个运行中的程序
- 内存指针
- 程序计数器(保存下一步即将执行的指令)
- 上下文数据
- 标识符PID
- 进程状态
- 优先级(交互性进程的优先级最高、批处理进程运行在后台,一直在循环默默处理,为了让操作系统运行更加良好)
- 记账信息(一个进程在cpu上运行的时间信息)
- I/O信息(文件I/O操作相关的信息)…
Cpu的分时机制:每个程序在cpu上运行都有一个时间片,时间片运行完毕则调度切换。
- 时间片:程序在cpu上运行的一段时间,这段时间运行完毕则调度切换。
如何查看进程的命令:
- ps -aux(a:所有;u:添加用户信息,相比-ef信息更详细)
- ps -ef (查看所有的进程信息)
- Pid_t getpid(void) 获取调用进程的ID
进程状态:运行 就绪 阻塞
linux下的运行状态:运行状态 R / 可中断休眠状态 S / 不可中断休眠状态 D / 停止状态T / 死亡状态 X / 追踪状态 t / 僵死状态 Z
僵死状态:处于僵死状态的进程
- 僵尸进程:进程已经退出,但是资源没有完全释放
- 僵尸状态的产生:
子进程先于父进程退出,为了保存退出原因,资源并没有完全被释放;因此在子进程退出时,操作系统会通知父进程,让父进程获取子进程的退出原因,然后释放子进程所有资源。如果父进程当前并没有关注子进程的退出状态,则子进程成为僵尸进程。 - 僵尸进程的危害:资源泄漏
- 僵尸进程的避免:进程等待
- 僵尸进程的处理:退出父进程
孤儿进程
- 父进程先于子进程退出,子进程会成为孤儿进程,运行在后台,父进程成为1号进程(init进程)(孤儿进程退出不会成为僵尸进程)
守护进程/精灵进程:特殊的孤儿进程(在孤儿进程的基础上,脱离终端脱离登录会话)(通常运行在后台,默默工作,不希望收到终端会话的影响)
4. 进程控制
进程创建:pid_t fork(void)
进程优先级:决定进程cpu资源的优先分配权
程序分类:CPU密集/IO密集
进程分类:批处理/交互式
Renice -n 19 -p pid
设置进程优先级(I/O密集性程序不需要设置优先级)
- Linux下Proc目录:process的简称;里面存放当前运行的进程信息
竞态条件:多个执行流竞争执行
函数的可重入与不可重入:
- 函数的重入:多个执行流同时进入一个函数执行代码
- 可重入:函数重入不会造成数据二义,或者逻辑混乱。
- 不可重入:函数重入又可能会造成数据二义,或者逻辑混乱。
关键点:是否对全局数据进行的非原子安全操作
SIGCHLD信号:子进程退出后操作系统给父进程发送的通知信息
- 这个信号默认的处理方式,就是什么也不做,因此子进程退出后在不等待的情况下会成为僵尸进程。
- 这个信号是一个非可靠信号,意味着有大量子进程同时退出的时候,有可能造成事件丢失。
ps:volatile关键字
- 保持内存的可见性,防止编译器过度优化。
- cpu每次都需要重新到内存中获取被修饰的变量的数据。
//编译器代码优化
Gcc---O0/1/2
5.多线程
线程概念:Linux下的线程是一个轻量级进程,是通过进程pcb描述实现的,并且同一个线程组(进程)中的线程公用同一个虚拟地址空间,因此这个linux下的pcb相较于pcb更加轻量化,因此叫轻量级进程。
- 线程是cpu调度的基本单位/进程是系统资源分配的基本单位
说明:
- 在传统的操作系统中,pcb就是进程,线程有个tcb;
- 但在linux下,因为线程是通过进程的pcb描述实现的,因此linux下的pcb实际是一个线程,并且因为这些线程公用同一块虚拟地址空间,因此,也把linux下的线程称为轻量级进程,相较于传统pcb更加轻量化。
进程VS线程
- pcb是轻量级进程(线程),进程是一个线程组
- Linux下,线程是cpu调度的基本单位(因为是一个pcb),而进程是资源分配的基本单位(因为一个程序运行起来虚拟地址空间、页表之类的都是分配给整个pcb的,分配给线程组、整个进程的)。
6. 多线程/多进程进行多任务处理的优缺点分析:
多线程优点:
- 因为共用同一块虚拟地址空间,因此线程间通信更加方便灵活(全局、传参)
- 线程的创建与销毁成本更低(创建进程需要创建pcb/页表/虚拟地址空间等等分配资源)
- 线程间的切换调度成本更低
多进程优点:
- 稳定、健壮性高-----适用于对主程序安全稳定性要求较高的场景:shell/服务器
7.进程地址空间(分页/虚拟地址空间)
程序地址空间
- 变量内容不一样,所以父子进程输出的变量绝对不是同一个变量
- 但地址值是一样的,说明,该地址绝对不是物理地址!
- 在Linux地址下,这种地址叫做 虚拟地址
- 我们在用C/C++语言所看到的地址,全部都是虚拟地址!物理地址,用户一概看不到,由OS统一管理
OS必须负责将 虚拟地址 转化成 物理地址 。
进程地址空间
总结:上图说明,同一个变量,地址相同,其实只是虚拟地址相同,内容不同其实是被映射到了不同的物理地址。