(五)进程相关函数,孤儿进程,僵尸进程

进程相关函数使用

os.getpid()
功能:获取当前进程的PID号
返回值:返回PID号

os.getppid()
功能:获取父进程的进程号
返回值:返回PID号

os._exit(status)
功能:退出进程
参数:进程的退出状态 整数

import os 

pid = os.fork()

if pid < 0:
    print("Create Process failed")
elif pid == 0:
    print("子进程PID",os.getpid())
    print("Parent PID",os.getppid())
else:
    print("父进程PID",os.getpid())
    print("Child PID",pid)
import os 
import sys 
#进程结束
# os._exit(0)
try:
    sys.exit("进程退出")
except SystemExit as e:
    print(e)
print("Process end")
#创建二级子进程
import os 
from time import sleep 
def fun1():
    sleep(3)
    print("第一件事情")
def fun2():
    sleep(4)
    print("第二件事情")
pid = os.fork()
if pid < 0:
    print("Create process error")
elif pid == 0:
    #创建二级进程
    pid0 = os.fork()
    if pid0 < 0:
        print("创建二级进程失败")
    elif pid0 == 0:
        fun2()  #做第二件事
    else:
        os._exit(0)
else:
    os.wait()
    fun1() #做第一件事


sys.exit([status])

功能: 退出进程
参数: 不写默认为0

    传入一个整数表示退出状态
    传入一个字符串,则在进程退出时会打印该字符串

* sys.exit 可以通过捕获 SystemExit 异常阻止其退出

import os,sys 
from time import sleep 
pid = os.fork()
if pid < 0:
    print("create process failed")
elif pid == 0:
    print("父进程pid:",os.getppid())
    sleep(2)
    print("父进程PID:",os.getppid())
else: 
    sleep(1)
    print("Parent PID:",os.getpid())
    sys.exit("父进程退出")
​​​​​​​import os,sys 
from time import sleep
pid = os.fork()
​​​​​​​if pid < 0:
    print("create process failed")
elif pid == 0:
    print("子进程PID:",os.getpid())
    sys.exit("子进程退出")
else: 
    sleep(1)
    while True:
        pass    
def fun(a):
    a = "Nihao China"
s = "hello world"
fun(s)
print(s)

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

* 孤儿进程会被系统指定的进程收养,即系统进程会成为该孤儿进程新的父进程,孤儿进程退出时该父进程会处理退出状态

僵尸进程:子进程先于父进程退出,父进程没有处理子进程退出状态,此时子进程成为僵尸进程

* 僵尸进程已经结束,但是会滞留部分PCB信息在内存,大量的僵尸会消耗系统资源,应该尽量避免

如何避免僵尸进程产生
* 父进程先退出

* 父进程处理子进程退出状态

pid,status = os.wait()
功能:在父进程中阻塞等待处理子进程的退出
返回值:pid 退出的子进程的PID号
       status  子进程的退出状态

pid,status = os.waitpid(pid,option)
功能:同wait
参数:pid  -1  表示任意子进程退出
           >0  整数  指定PID号的子进程退出
    option  0  表示阻塞等待
           WNOHANG 表示非阻塞
返回值:同wait

waitpid(-1,0)  ====  wait()

 
* 父进程先退出
创建二级子进程
    1.父进程创建子进程等待子进程退出
    2.子进程创建二级子进程,然后马上退出
    3.二级子进程成为孤儿,处理具体事件
     
multiprocessing 模块创建进程
1.需要将要做的事件封装为函数
2.使用multiprocessing中提供的process类创建进程
3.通过进程对象和process 初始化函数对进程进行设置,并且绑定要执行的事件
4.启动进程,会自动执行相关联函数
5.事件完成后回收进程

创建进程对象

process()
功能:创建进程对象
参数:name : 给创建的进程对象起一个名字
            默认process-1
    target : 绑定的函数

    args : 元组 给target函数按照位置传参
    kwargs : 字典 给target函数按照键值出传参

p.start()
功能: 启动进程,此时进程被创建。自动运行进程函数

p.join([timeout])
功能:阻塞等待回收响应的进程
参数:超时时间

* multiprocessing创建进程是原来进程的子进程,创建后父子进程各自执行互不影响
* 子进程同样是复制父进程的空间,子进程对内容的修改不会影响父进程空间
* join回收子进程,会有效的阻止僵尸进程产生

import multiprocessing as mp 
from time import sleep 
import os 
a = 1
#进程事件
def fun():
    # print("a = ",a)
    global a 
    a = 10000
    print(os.getpid())
    sleep(3)
    print("子进程事件")
p = mp.Process(target = fun)#创建进程对象
p.start()#启动进程
sleep(2)
print("这是父进程")
p.join()​​​​​​​#回收进程
while True:
    pass
print("===================")
# print(a)
import os,sys 
from time import sleep
pid = os.fork()
​​​​​​​if pid < 0:
    print("create process failed")
elif pid == 0:
    sleep(3)
    print("子进程PID:",os.getpid())
    sys.exit(3)
else: 
    #等待子进程退出
    pid,status = os.wait()
    print(pid,status)
    print(os.WEXITSTATUS(status)) #获取退出状态
    while True:
        pass  
import os,sys 
from time import sleep
pid = os.fork()
​​​​​​​if pid < 0:
    print("create process failed")
elif pid == 0:
    sleep(3)
    print("子进程PID:",os.getpid())
    sys.exit(3)
else: 
    #等待子进程退出
    while True:
        sleep(1)
        pid,status = os.waitpid(-1,os.WNOHANG)
        print(pid,status)
        if os.WEXITSTATUS(status):
            break
        print("do something others")
    while True:
        pass  

作业: multipeocessing  对照fork
      创建父子进程,复制一个文件,父子进程各复制一半到一个新的文件中

import os 
from multiprocessing import Process
from time import sleep

size = os.path.getsize("./img.jpg")
# 如果在父进程打开则两个子进程操作同一个文件流
# fr = open('img.jpg','rb')

#复制上半部分
def copy1(filename):
    fr = open(filename,'rb')
    n = size // 2 
    fw = open('copy1.jpg','wb')

    while True:
        if n < 1024:
            data = fr.read(n)
            fw.write(data)
            break
        data = fr.read(1024)
        fw.write(data)
        n -= 1024
    fr.close()
    fw.close()

#复制下半部分
def copy2(filename):
    fr = open(filename,'rb')
    fw = open('copy2.jpg','wb')
    fr.seek(size // 2,0)  #文件偏移位置到中间

    while True:
        data = fr.read(1024)
        if not data:
            break 
        fw.write(data)
    fw.close()
    fr.close()

p1 = Process(target = copy1,args = ("img.jpg",))
p2 = Process(target = copy2,args = ("img.jpg",))

p2.start()
sleep(0.5)
p1.start()

p1.join()
p2.join()

猜你喜欢

转载自blog.csdn.net/zh__quan/article/details/81213299