import os
pid = os.fork()
功能:创建新的进程
参数:无
返回值:失败返回一个负数
成功:在原有进程中返回新的进程的PID号
在新的进程中返回0
- fork函数演示于进程的特征
一般情况下父进程在子进程之前运行
#此程序演示多进程编程中fork函数以及进程的特征
import os
from time import sleep
print('***********')
a = 1
pid = os.fork()
#父进程创建时返回子进程的pid号
#子进程返回值是0
#子进程复制父进程的代码,从父进程的fork语句下开始继续执行
if pid < 0:
print('创建进程失败')
elif pid == 0:
print('这是子进程',os.getppid())
#子进程虽然不执行父进程中a = 1的赋值语句
#但是复制了父进程的内容
print("Son's a = ",a)
a = 1000
else:
print('这是父进程',os.getpid())
#使用sleep函数保证父进程在子进程之后执行
#用来证明父子进程之后是独立的运行单元,互不干扰
sleep(1)
print("Father's a = ",a)
print('演示完毕')
1.子进程会复制父进程的全部代码段,包括fork之前产生的内存
空间
2.子进程从fork的下一句开始执行,与父进程互不干扰
3.父子进程的执行顺序是不一定的,父子进程公用一个终端显示
4.父子进程会根据fork返回值得差异选择执行不同得代码。所以
if结构几乎是fork得固定搭配
5.父子进程空间独立,操作的都是本空间得内容,互不影响
6.子进程也有自己的特性,比如PID号,PCB,命令集等
1.获取进程PID
os.getpid()
功能:获取当前进程的进程号
返回值:返回进程号
os.getppid()
功能:获取当前进程父进程PID号
返回值:返回进程号
*父进程打印子进程的PID号只需要打印fork函数的返回值
2.进程退出
os._exit(status)
功能: 进程退出
参数: 进程的退出状态
sys.exit([status])
功能: 进程退出
参数: 数字表示退出状态,不写默认为0
字符串表示打印的内容
*sys.exit可以通过捕获SystemExit异常阻止退出
#此程序用来演示进程退出方式
import sys, os
#结束进程后不再执行后面内容
#os._exit(0)
try:
sys.exit('退出进程')
except SystemExit as e:
print('退出:',e)
#处理完异常以下代码能够正常执行
print('process exit')
- 孤儿进程
父进程先于子进程退出,此时子进程就称为孤儿进程
*孤儿进程会被操作系统指定的进程收养,系统进程就成为了孤儿进程父进程 - 僵尸进程
1.子进程先于父进程退出
2.父进程没有处理子进程的退出状态,此时子进程就会成为僵尸进程
*僵尸进程会存留少量PCB信息在内存中,大量的僵尸进程会消耗系统资源,应该避免僵尸进程 - 如何避免僵尸进程的产生
* 处理子进程退出状态
pid,status = os.wait()
功能: 在父进程中阻塞等待处理子进程退出
返回值: pid 退出的子进程的PID号
status 获取子进程退出状态
pid,status = os.waitpid(pid,option)
功能: 在父进程中阻塞等待处理子进程退出
参数: pid -1 表示等待任意子进程退出
>0 表示等待对应PID号的子进程退出
option 0 表示阻塞等待
os.WNOHANG 表示非阻塞
waitpid(-1,0) ===》wait()
* 让父进程先退出
1.父进程创建子进程等待子进程退出
2.子进程创建二级子进程后退出
3.二级子进程成为孤儿,和原来的父进程各自执行事件
#此进程用来避免僵尸进程的产生
#方法是处理子进程的退出状态
import os
from time import sleep
pid = os.fork()
if pid < 0:
print('create process failed')
elif pid == 0:
sleep(3)
print('这是子进程',os.getpid())
os._exit(3)
else:
#获取子进程退出状态
while True:
sleep(1)
#通过非阻塞形式捕获子进程退出
pid,status = os.waitpid(-1,os.WNOHANG) # 非阻塞处理子进程,不加while将无法处理
print(os.WEXITSTATUS(status)) # 获取子进程退出状态 = _exit参数
print(pid,status) # status = _exit参数*256
while True:
pass
#避免僵尸进程的产生
#方法是先让父进程退出,创建二级子进程成为孤儿完成任务
import os
from time import sleep
def f1():
sleep(3)
print('第一件事')
def f2():
sleep(4)
print('第二件事')
pid = os.fork()
if pid < 0:
print('create process failed')
elif pid == 0:
print('这是一级子进程',os.getpid())
#创建二级子进程
p = os.fork()
if p < 0:
print('failed')
elif p == 0:
#二级子进程完成第二件事
print('这是二级子进程,准备做第二件事')
f2()
else:
#一级子进程退出
print('一级子进程退出')
os._exit(0)
else:
os.wait() # 等待一级子进程退出
print('这里是父进程,已捕捉到一级子进程退出完毕')
f1() # 做第一件事
