目录
- 操作系统发展史
- 进程
- 进程互斥锁
- 队列
- 堆栈
- IPC(进程间通信)
- 生产者与消费者
- 线程
- 什么是线程
- 为什么要使用线程
- 开启进程
- 开启线程
- 线程互斥锁
操作系统发展史
穿孔卡片
联机批处理
脱机批处理
多道技术:
单道:多个程序一串串执行
多道:
切换+保存状态
空间上的复用
一个计算机(CPU)的空间可以提供给多个程序使用.
时间上的复用
当前程序遇到IO操作,就会立马切换CPU的执行权限
当前程序使用CPU时间过长,就会立马切换CPU的执行权限
并发与并行
- 并发:看起来像同时运行。
- 并行:真是意义上的同时运行。
- 在单核的情况下不能实现并行,要想实现并行,必须有多个CPU
进程
程序:一堆代码。
进程:一堆代码运行的过程。
进程调度:时间片论法 + 分级反馈队列
进程的三种状态:
就绪态
所有进程在创建时都会先进入就绪态
运行态
通过进程调度将每一个进程调入运行态
阻塞态
在运行态中的程序遇到IO就会进入阻塞态
若IO结束,会立马进入就绪态,不会直接进入运行态
注意:CPU的执行时间过长会看起来像阻塞,其实并不是阻塞,剥夺其CPU执行权限,然后会将该进程重新返回就绪态。
同步与异步
- 同步:一个任务提交后,在原地等待该任务结束后,下一个才能提交并且执行
- 异步:一个任务提交后,不需要原地等待,立马可以执行下一个任务
阻塞与非阻塞
- 阻塞:阻塞态(遇到IO,会进入阻塞态)
- 非阻塞:就绪态、运行态
创建进程的两种方式
from multiprocessing import Process
import time
方式一:
def task(): print('子进程开始执行') time.sleep(1) print('子进程结束完毕') # 在windows系统下创建,必须要再__main__执行 - __main__ 下: # target = 执行任务(函数地址) p = Process(target = task) p.start() #告诉操作系统,创建子进程 # join p.join() # 让主进程等待所有子进程结束后才能结束 print('主进程')
方式二:
- 自定义类,继承Process class Myprocess(Process): def run(self): # 此处是子进程的任务 print('子进程开始执行') time.sleep(1) print('子进程结束完毕') - __main__下: p = MyProcess() p.start() # 告诉操作系统,创建子进程 # join p.join() # 让主进程等待所有子进程结束后才结束 print('主进程')
- join() 让主进程等待所有子进程结束后才能结束
- 进程间数据是隔离的
- 进程对象的属性
# 可以获取子进程 pid号 current_process().pid --->return Process().pid # 在子进程中打印是子进程的pid号,在父进程中打印父进程的pid号 os.getpid() # 主主进程pid号 os.getppid() current_process()-->p # 终止子进程 p.terminate() # 判断进程是否存活 is_alive
守护进程
主进程结束后,子进程也要跟着结束
# 注意:必须要在start()之前设置 p.daemon = True p.start() # p.daemon = True 报错
父进程回收子进程PID号的两种方式:
- join
- 父进程正常结束后
僵尸进程与孤儿进程(了解):
僵尸进程:子进程结束后,父进程没有回收
PID
,导致子进程永久保留PID
号缺点:占用
PID
号,占用操作系统资源孤儿进程:子进程还未结束,父进程意外结束,导致子进程在结束后父进程无法回收
此使子进程就像一个"孤儿",然后由操作系统自带的"福利院"来回收.
进程互斥锁
让并发变成了串行,牺牲了执行效率,保证了数据安全
在程序并发执行时,需要修改数据时使用
队列
队列是先进先出
相当于内存中产生一个队列空间,可以存放多个数据,先进去的数据排在前面
堆栈
堆栈是先进后出
IPC(进程间通信)
进程间数据时相互隔离的,若想实现进程间通信,可以利用队列
生产者与消费者
生产者:生产数据的
消费者:使用数据的
在程序中:通过队列,生产者把数据添加队列中,消费者从队列中获取数据
线程
什么是线程
线程和进程都是虚拟单位,目的是为了更好的描述某件事物
- 进程:资源单位
- 线程:执行单位
为什么要使用线程
节省内存资源
开启进程
- 开辟一个名称空间, 每开启一个进程都会占用一份内存资源
- 会自带一个主线程
开启线程
- 一个进程可以开启多个线程
- 线程的开销远小于进程
注意:线程不能实现并行,线程只能实现并发,进程可以实现并行
线程互斥锁
线程之间数据是共享的