1.进程与程序
进程:一个正在运行中的程序 是一系列程序执行的过程的总称(抽象概念)
程序:是有程序员将自己的思维逻辑按照某种编程语言规范编写下来的一堆字符串,最终形成的一堆文件
进程是有由程序产生的.没有程序就没有进程
# 如何产生进程 与 进程的父子关系
# 运行一个程序就会产生一个进程
# py文件要运行 必须借助python解释器 所以启动的进程时python.exe
# 同一个程序可以多次运行 产生多个进程
# 每个进程都会随机分配一个PID(进程ID)
# 一个进程a 开启另一个进程b b就是a的子进程
import os
print(os.getpid()) # 自己的PID
print(os.getppid()) # 获取父进程的PID
进程间的独立性:
from multiprocessing import Process
import time
a = 10
def task():
print("子 run....")
global a
a = 1000
if __name__ == '__main__':
p = Process(target=task)
p.start() # 仅仅是发送一个信号 告诉操作系统要开子进程了 代码会立即往下执行
print(a)
print("over")
开启子进程的两种方式
1.直接实例化Process类 通过target参数来制定要执行的任务(一个函数)
2.可以继承Process类,覆盖run方法 将要执行的任务放到run方法中
注意:在windows中 开启子进程的代码 必须放在 if __name__=="__main__"中
防止子进程递归开启子进程
linux开启子进程 是直接copy一份相同的数据到子进程中
而windows需要读取代码执行一遍
2.操作系统与进程
应用程序无法直接运行在硬件之上,一定要借助操作系统,
所以进程是由操作系统创建的
操作系统本质也是一款软件,
与普通软件的区别?
操作系统是真正在控制硬件的
应用程序实在调用操作系统提供的接口
主要功能:
1.帮你封装隐藏了丑陋复杂的硬件操作,提供了简单的,优雅的接口
2.需要将各个应用程序对硬件的竞争变得有序
3.多道技术的演变
多道技术是为了解决同一时间只有一个应用程序被执行的问题
多道技术提高效率的原理就是通过空间复用和时间复用
空间复用:同一时间在内存中存放多个应用程序
时间复用:
切换
1.当一个程序A 在执行过程中与到IO操作(IO通常都是非常慢的) 操作系统就会切换到另一个程序执行
感觉像是多个应用程序都在执行 (并发)
2.当一个程序A 执行时间过长 也会强制切换到其他的应用程序,以此保证度多个程序都在执行
3.如果出现了一个优先级更高的任务 也会切换
保存状态
当一个操作系统要从一个进程切换至另一个进程时,必须保存当前进程的状态,以便下次切换回来的时候继续执行
强调:
多个进程之间内存要相互独立,并且是物理层面的隔离(程序是不可能修改的),以保证安全性
多道技术带来的好处
1.同一时间可以有多个应用程序在执行 在IO比较多时 极大的提高了效率
弊端:
如果所有应用程序都没有IO操作,反而会降低效率
应用程序的执行效率取决于IO操作,IO操作越多则效率越低.
提高效率:
1.减少IO
2.避免被操作系统切换
4.进程的状态
阻塞态
遇到IO操作了
运行态
就绪态
join函数:
from multiprocessing import Process
import time
a = 10
def task():
print("子 run....")
global a
a = 1000
time.sleep(2)
if __name__ == '__main__':
p = Process(target=task)
p.start() # 仅仅是发送一个信号 告诉操作系统要开子进程了 代码会立即往下执行
p.join() # 会使主进程等待子进程执行完毕后才会继续执行 # 内部修改p的优先级比主进程高
print(a)
print("over")
Process对象的常用属性:
from multiprocessing import Process
import time
def task():
print("11111111111111")
time.sleep(1)
print("over")
if __name__ == '__main__':
p = Process(target=task,name="这是造着玩的进程")
p.start()
# print(p.name) # 在创建时可以给进程取名字
p.join()
# print(p.exitcode) # 获取进程的退出码 只有进程完全结束后才能获取到
# print(p.pid) # 获取进程的pid
print(p.is_alive())
# p.terminate() # 终止进程 与start相同的是 都是给操作系统发送信号 发完继续执行 所以不会立即就终止成功
# # time.sleep(2)
# print( p.is_alive()) # 获取进程的存活状态
并发,并行,串行,阻塞:
默认情况下 代码是串行的
串行: 按照顺序依次执行 第一行执行完毕后才会执行第二行
需要注意的是 串行执行的过程中 因为计算操作太多也会导致程序卡住 但是这与io阻塞是不同的
io阻塞立马将CPU切到其他进程
而串行执行一堆计算任务 CPU没有切走
阻塞: 指的是进程的状态
并发: 指多个事件同时发生了(单核下就是通过切换+保存状态来实现 就是多道技术)
并行: 真正意义上的同时执行 (只在多核处理器才有可能出现)
6.僵尸进程和孤儿进程
linux中存在僵尸进程 与孤儿进程
linux 必须保证在任何时候 父进程都能查到子进程的信息
父进程已经结束了而子进程还在运行中 子进程称之为孤儿进程 无害的
孤儿进程 会统一交给init这个根进程来管理
僵尸进程
当子进程结束时 并不会立即从操作系统完全删除 会留一下进程信息 一共父进程查看 有害
python 已经自动帮你处理僵尸进程