zoukankan      html  css  js  c++  java
  • 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
    信号方法处理僵尸进程
  • 相关阅读:
    UVA 11925 Generating Permutations 生成排列 (序列)
    UVA 1611 Crane 起重机 (子问题)
    UVA 11572 Unique snowflakes (滑窗)
    UVA 177 PaperFolding 折纸痕 (分形,递归)
    UVA 11491 Erasing and Winning 奖品的价值 (贪心)
    UVA1610 PartyGame 聚会游戏(细节题)
    UVA 1149 Bin Packing 装箱(贪心)
    topcpder SRM 664 div2 A,B,C BearCheats , BearPlays equalPiles , BearSorts (映射)
    UVA 1442 Cave 洞穴 (贪心+扫描)
    UVA 1609 Foul Play 不公平竞赛 (构(luan)造(gao)+递归)
  • 原文地址:https://www.cnblogs.com/maplethefox/p/10989131.html
Copyright © 2011-2022 走看看