一什么是进程
进程: 正在进行的一个过程或是一个任务而负责执行任务的是 CPU
举例:(单核 + 多道, 实现多个进程的并发):
比如说你就是一个 CPU, 你下午有几个活要干, 吃饭, 洗衣服, 上厕所等但是就在那一下午要把所有的事干完(而 CPU 同一时间只能干一件事), 那么如何才能让多个任务实现并发执行的效果呢? 那么, 你应该这样做, 你可以先做饭, 在等待饭熟的过程中你可以去洗个衣服, 洗的差不多饭也就熟了, 那么你在去上个厕所也可以嘛
二进程与程序的区别
程序仅仅只是一堆代码而已, 而进程指的是程序的运行过程
需要强调的是: 同一程序执行两次, 那也是进程, 比如登录 QQ, 虽然都是同一个软件, 但是一个可以视频聊天, 一个可以逛空间
三并发和并行
并发: 单 CPU, 多进程并发
无论是并行还是并发, 在用户看来都是同时运行的, 不管是进程还是线程, 都只是一个任务而已, 真实干活的是 cpu,cpu 来做这些任务, 而一个 cpu 同一时刻只能执行一个任务
一 并发: 是伪并行, 即看起来是同时运行单个 cpu + 多道技术就可以实现并发,(并行也属于并发)
你是一个 cpu, 你同时谈了三个女朋友, 每一个都可以是一个恋爱任务, 你被这三个任务共享 2 要玩出并发恋爱的效果, 3 应该是你先跟女友 1 去看电影, 看了一会说: 不好, 我要拉肚子, 然后跑去跟第二个女友吃饭, 吃了一会说: 那啥, 我 4 去趟洗手间, 然后跑去跟女友 3 开了个房
并行: 多 CPU(同时运行, 只有具有多个 cpu 才能实现并行)
单核下, 可以利用多道技术, 多个核, 每个核也都可以利用多道技术(多道技术是针对单核而言的)
有四个核, 六个任务, 这样同一时间有四个任务被执行, 假设分别被分配给了 cpu1,cpu2,cpu3,cpu4,
一旦任务 1 遇到 I/O 就被迫中断执行, 此时任务 5 就拿到 cpu1 的时间片去执行, 这就是单核下的多道技术
而一旦任务 1 的 I/O 结束了, 操作系统会重新调用它(需知进程的调度分配给哪个 cpu 运行, 由操作系统说了算), 可能被分配给四个 cpu 中的任意一个去执行
所有现代计算机经常会在同一时间做很多件事, 一个用户的 PC(无论是单 cpu 还是多 cpu), 都可以同时运行多个任务(一个任务可以理解为一个进程)
多道技术: 内存中同时存入多道 (多个) 程序, cpu 从一个进程快速切换到另外一个, 使每个进程各自运行几十或几百毫秒, 这样, 虽然在某一个瞬间, 一个 cpu 只能执行一个任务, 但在 1 秒内, cpu 却可以运行多个进程, 这就给人产生了并行的错觉, 即伪并发, 以此来区分多处理器操作系统的真正硬件并行(多个 cpu 共享同一个物理内存)
四同步和异步
同步执行: 一个进程在执行某个任务时, 另外一个进程必须等待其执行完毕, 才能继续执行
异步执行: 一个进程在执行某个任务时, 另外一个进程无需等待其执行完毕, 就可以继续执行, 当有消息返回时, 系统会通知后者进行处理, 这样可以提高执行效率
举个例子, 打电话时就是同步通信, 发短息时就是异步通信
五进程的创建
但凡是硬件, 都需要有操作系统去管理, 只要有操作系统, 就有进程的概念, 就需要有创建进程的方式, 一些操作系统只为一个应用程序设计, 比如微波炉中的控制器, 一旦启动微波炉, 所有的进程都已经存在
而对于通用系统(跑很多应用程序), 需要有系统运行过程中创建或撤销进程的能力, 主要分为 4 中形式创建新的进程
1. 系统初始化(查看进程 linux 中用 ps 命令, windows 中用任务管理器, 前台进程负责与用户交互, 后台运行的进程与用户无关, 运行在后台并且只在需要时才唤醒的进程, 称为守护进程, 如电子邮件 web 页面新闻打印)
2. 一个进程在运行过程中开启了子进程(如 nginx 开启多进程, os.fork,subprocess.Popen 等)
3. 用户的交互式请求, 而创建一个新进程(如用户双击暴风影音)
4. 一个批处理作业的初始化(只在大型机的批处理系统中应用)
无论哪一种, 新进程的创建都是由一个已经存在的进程执行了一个用于创建进程的系统调用而创建的:
1. 在 UNIX 中该系统调用是: fork,fork 会创建一个与父进程一模一样的副本, 二者有相同的存储映像同样的环境字符串和同样的打开文件(在 shell 解释器进程中, 执行一个命令就会创建一个子进程)
2. 在 windows 中该系统调用是: CreateProcess,CreateProcess 既处理进程的创建, 也负责把正确的程序装入新进程
关于创建的子进程, UNIX 和 windows
1. 相同的是: 进程创建后, 父进程和子进程有各自不同的地址空间(多道技术要求物理层面实现进程之间内存的隔离), 任何一个进程的在其地址空间中的修改都不会影响到另外一个进程
2. 不同的是: 在 UNIX 中, 子进程的初始地址空间是父进程的一个副本, 提示: 子进程和父进程是可以有只读的共享内存区的但是对于 windows 系统来说, 从一开始父进程与子进程的地址空间就是不同的
六进程的终止
1. 正常退出(自愿, 如用户点击交互式页面的叉号, 或程序执行完毕调用发起系统调用正常退出, 在 linux 中用 exit, 在 windows 中用 ExitProcess)
2. 出错退出(自愿, python a.py 中 a.py 不存在)
3. 严重错误(非自愿, 执行非法指令, 如引用不存在的内存, 1/0 等, 可以捕捉异常, try...except...)
4. 被其他进程杀死(非自愿, 如 kill -9)
七进程的层次结构
无论 UNIX 还是 windows, 进程只有一个父进程, 不同的是:
1. 在 UNIX 中所有的进程, 都是以 init 进程为根, 组成树形结构父子进程共同组成一个进程组, 这样, 当从键盘发出一个信号时, 该信号被送给当前与键盘相关的进程组中的所有成员
2. 在 windows 中, 没有进程层次的概念, 所有的进程都是地位相同的, 唯一类似于进程层次的暗示, 是在创建进程时, 父进程得到一个特别的令牌(称为句柄), 该句柄可以用来控制子进程, 但是父进程有权把该句柄传给其他子进程, 这样就没有层次了
八进程的状态
tail -f access.log |grep 404
执行程序 tail, 开启一个子进程, 执行程序 grep, 开启另外一个子进程, 两个进程之间基于管道 | 通讯, 将 tail 的结果作为 grep 的输入
进程 grep 在等待输入 (即 I/O) 时的状态称为阻塞, 此时 grep 命令都无法运行
其实在两种情况下会导致一个进程在逻辑上不能运行,
1. 进程挂起是自身原因, 遇到 I/O 阻塞, 便要让出 CPU 让其他进程去执行, 这样保证 CPU 一直在工作
2. 与进程无关, 是操作系统层面, 可能会因为一个进程占用时间过多, 或者优先级等原因, 而调用其他的进程去使用 CPU
因而一个进程由三种状态
九进程并发的现象
进程并发的实现在于, 硬件中断一个正在运行的进程, 把此时进程运行的所有状态保存下来, 为此, 操作系统维护一张表格, 即进程表(process table), 每个进程占用一个进程表项(这些表项也称为进程控制块)
来源: http://www.bubuko.com/infodetail-2500787.html