Python并发编程2——基于fork的多进程编程

基于fork的多进程编程

fork使用

pid = os.fork()
功能: 创建新的进程
返回值:整数,如果创建进程失败返回一个负数,如果成功则在原有进程中返回新进程的PID,在新进程中返回0

注意:
子进程会复制父进程全部内存空间,从fork下一句开始执行。
父子进程各自独立运行,运行顺序不一定。
利用父子进程fork返回值的区别,配合if结构让父子进程执行不同的内容几乎是固定搭配。
父子进程有各自特有特征比如PID PCB 命令集等。
父进程fork之前开辟的空间子进程同样拥有,父子进程对各自空间的操作不会相互影响。


  	 '''
        fork示例
     '''
    import os
    from time import  sleep

    pid = os.fork()  #Windows没有fork调用,推荐大家在Unix/Linux或mac系统下运行

    if pid <0:
        print("Create process failed")

    elif pid ==0:
        sleep(5)
        print("The new process")

    else:
        sleep(6)
        print("The old process")

    print("Fork test over")


进程相关函数

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

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

os._exit(status)
功能: 结束一个进程
参数:进程的终止状态

sys.exit([status])
功能:退出进程
参数:整数 表示退出状态
字符串 表示退出时打印内容

孤儿和僵尸

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

  2. 僵尸进程 : 子进程先于父进程退出,父进程又没有处理子进程的退出状态,此时子进程就会称为僵尸进程。
    特点: 僵尸进程虽然结束,但是会存留部分PCB在内存中,大量的僵尸进程会浪费系统的内存资源。

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

  • 使用wait函数处理子进程退出
    pid,status = os.wait()
    功能:在父进程中阻塞等待处理子进程退出
    返回值: pid  退出的子进程的PID
       status  子进程退出状态
    
    pid,status = os.waitpid(pid,option)
    功能: 在父进程中处理子进程退出状态
    参数: pid  -1  表示等待任意子进程退出
           >0  表示等待指定的子进程退出			 
         option  0  表示阻塞等待
                 WNOHANG  表示非阻塞
    返回值:pid  退出的子进程的PID
          status  子进程退出状态 
    

    '''
        wait示例
    '''

    import os

    pid = os.fork()

    if pid <0:
        print("Error")

    elif pid ==0:
        print("Child process",os.getpid())
        os._exit(2)
    else:
        pid,status = os.wait()
        print("pid",pid)
        print("status",os.WEXITSTATUS(status))

        while True:
            pass


-----------------------------------------
    import os
    from time import *


    def f1():
        for i in range(4):
            sleep(2)
            print("写代码...")


    def f2():
        for i in range(5):
            sleep(1)
            print("测代码")


    pid = os.fork()

    if pid < 0:
        print("Error")

    elif pid == 0:
        p = os.fork()
        if p == 0:
            f2()

        else:
            os._exit(0)
    else:
        os.wait()
        f1()

  • 创建二级子进程处理僵尸

代码示例:day1/child.py

1】 父进程创建子进程,等待回收子进程
【2】 子进程创建二级子进程然后退出
【3】 二级子进程称为孤儿,和原来父进程一同执行事件
  • 通过信号处理子进程退出

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

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

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

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

    '''
        signal示例
    '''

    import os
    import signal

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

    pid = os.fork()

    if pid < 0:
        print("Error")
    elif pid == 0:
        print("Child pid", pid)
    else:
        print("Parent pid", os.getpid())
        os._exit(0) 

-----------------------------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值