• Python并发编程—fork的使用


    基于fork的多进程编程

    fork使用

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

    注意:

    • 子进程会复制父进程全部内存空间,从fork下一句开始执行。
    • 父子进程各自独立运行,运行顺序不一定。
    • 利用父子进程fork返回值的区别,配合if结构让父子进程执行不同的内容几乎是固定搭配。
    • 父子进程有各自特有特征比如PID PCB 命令集等。
    • 父进程fork之前开辟的空间子进程同样拥有,父子进程对各自空间的操作不会相互影响。
     1 import os
     2 from time import sleep
     3 
     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 import os
     2 from time import sleep
     3 
     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 import os
     4 import time
     5 
     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 import os
    2 import sys
    3 
    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 import os
     2 
     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   while True:
    16     pass
    wait 处理僵尸

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

    1. 父进程创建子进程,等待回收子进程
    2. 子进程创建二级子进程然后退出
    3. 二级子进程称为孤儿,和原来父进程一同执行事件
     1 import os
     2 from time import sleep
     3 
     4 def f1():
     5   for i in range(4):
     6     sleep(2)
     7     print("写代码")
     8 
     9 def f2():
    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 import signal
     2 import os
     3 
     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   while True:
    15     pass
    信号方法处理僵尸进程
  • 相关阅读:
    巧用SQL生成SQL语句
    update,delete与INNER JOIN 以及删除重复数据
    sql判断各种类型的东西存在与否(参考)
    附加数据库报错823
    hibernate配置文件hibernate.cfg.xml的详细解释
    向数据库插入图片以及从数据库中读取图片并显示到jsp(数据库中存储的图片字段类型为Blob或image)
    Hibernate中hibernateTemplate()方法总结
    spring MVC之构造ModelAndView对象
    手机网站初步布局,如何建立你自己的手机网站?
    (MoMoCMS教程2)创建页面——主菜单
  • 原文地址:https://www.cnblogs.com/maplethefox/p/10989131.html
Copyright © 2020-2023  润新知