python fork_Python并发编程—fork的使用

本文详细介绍了基于fork的进程创建,包括fork函数的使用、父子进程的执行顺序、进程的PID获取以及孤儿和僵尸进程的处理。通过示例代码展示了wait函数和信号处理如何避免僵尸进程的产生,强调了进程间独立性和资源管理的重要性。
摘要由CSDN通过智能技术生成

基于fork的多进程编程

fork使用

pid = os.fork()

功能: 创建新的进程

返回值:整数,如果创建进程失败返回一个负数,如果成功则在原有进程中返回新进程的PID,在新进程中返回0

注意:

子进程会复制父进程全部内存空间,从fork下一句开始执行。

父子进程各自独立运行,运行顺序不一定。

利用父子进程fork返回值的区别,配合if结构让父子进程执行不同的内容几乎是固定搭配。

父子进程有各自特有特征比如PID PCB 命令集等。

父进程fork之前开辟的空间子进程同样拥有,父子进程对各自空间的操作不会相互影响。

1 importos2 from time importsleep3

4 pid =os.fork()5

6 if pid <0:7 print("Create process failed")8 elif pid ==0:9 os._exit(0)10 sleep(3)11 print("New process")12 else:13 sleep(5)14 print("Old process")15

16 print("Fork test end")

基于fork的进程创建演示1

1 importos2 from time importsleep3

4 print("=========================")5 a = 1

6

7 pid =os.fork()8

9 if pid <0:10 print("Create process failed")11 elif pid ==0:12 print("New process")13 print("a =",a)14 a = 10000

15 else:16 sleep(1)17 print("Old process")18 print("a:",a)19

20 print("All a =",a)

基于fork的进程创建演示2

进程相关函数

os.getpid()

功能: 获取一个进程的PID值

返回值: 返回当前进程的PID

os.getppid()

功能: 获取父进程的PID号

返回值: 返回父进程PID

1 #获取pid值

2

3 importos4 importtime5

6 pid =os.fork()7

8 if pid <0:9 print("Error")10 elif pid ==0:11 time.sleep(1)12 print("Child PID:",os.getpid())13 print("Get parent PID:",os.getppid())14 else:15 print("Get child PID:",pid)16 print("Parent PID:",os.getpid())

get_pid

os._exit(status)

功能: 结束一个进程

参数:进程的终止状态

sys.exit([status])

功能:退出进程

参数:整数 表示退出状态

字符串 表示退出时打印内容

1 importos2 importsys3

4 #os._exit(1)

5 sys.exit("退出进程")6

7 print("Process exit")

exit

孤儿和僵尸

1.孤儿进程 : 父进程先于子进程退出,此时子进程成为孤儿进程。

特点: 孤儿进程会被系统进程收养,此时系统进程就会成为孤儿进程新的父进程,孤儿进程退出该进程会自动处理。

2.僵尸进程 : 子进程先于父进程退出,父进程又没有处理子进程的退出状态,此时子进程就会称为僵尸进程。

特点: 僵尸进程虽然结束,但是会存留部分PCB在内存中,大量的僵尸进程会浪费系统的内存资源。

3.如何避免僵尸进程产生

1)使用wait函数处理子进程退出

```

pid,status = os.wait()

功能:在父进程中阻塞等待处理子进程退出

返回值: pid 退出的子进程的PID

status 子进程退出状态

```

1 importos2

3 pid =os.fork()4

5 if pid <0:6 print("Error")7 elif pid ==0:8 print("Child process",os.getpid())9 os._exit(3)10 else:11 p,status = os.wait() #阻塞等待子进程退出

12 print("p :",p)13 #还原退出状态

14 print("status:",os.WEXITSTATUS(status))15 whileTrue:16 pass

wait 处理僵尸

2)创建二级子进程处理僵尸

父进程创建子进程,等待回收子进程

子进程创建二级子进程然后退出

二级子进程称为孤儿,和原来父进程一同执行事件

1 importos2 from time importsleep3

4 deff1():5 for i in range(4):6 sleep(2)7 print("写代码")8

9 deff2():10 for i in range(5):11 sleep(1)12 print("测代码")13

14 pid =os.fork()15 if pid <0:16 print("Error")17 elif pid ==0:18 p = os.fork() #二级子进程

19 if p ==0:20 f2()21 else:22 os._exit(0) #一级子进程退出

23 else:24 os.wait() #等一级子进程退出

25 f1()

二级子进程处理僵尸

3)通过信号处理子进程退出

原理: 子进程退出时会发送信号给父进程,如果父进程忽略子进程信号,则系统就会自动处理子进程退出。

方法: 使用signal模块在父进程创建子进程前写如下语句 :

import signal

signal.signal(signal.SIGCHLD,signal.SIG_IGN)

特点 : 非阻塞,不会影响父进程运行。可以处理所有子进程退出

1 importsignal2 importos3

4 #子进程退出时父进程会忽略,此时子进程自动由系统处理

5 signal.signal(signal.SIGCHLD,signal.SIG_IGN)6

7 pid =os.fork()8

9 if pid <0:10 pass

11 elif pid ==0:12 print("Child pid:",os.getpid())13 else:14 whileTrue:15 pass

信号方法处理僵尸进程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值