python的多任务编程实现

博客围绕多进程编程展开,介绍了fork函数及进程特征,通常父进程先于子进程运行。重点讲解了孤儿进程和僵尸进程,前者是父进程先退出被系统进程收养,后者是子进程先退出且父进程未处理退出状态,还提及避免僵尸进程的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 多进程编程
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() # 做第一件事

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值