美文网首页
02Python学习笔记之二.七【多任务、fork、getp(p

02Python学习笔记之二.七【多任务、fork、getp(p

作者: 平知 | 来源:发表于2019-08-19 07:38 被阅读0次
    章节号 内容            
    1图片格式(png) 宽度大于620px,保持高宽比减低为620px
    1-1 应用
    1-1-1 方法

    第1章节  多任务概念理解

      

    第2章节  fork创建子进程

    • 1-1 fork创建子进程—简单测试

    In [1]: 
       ...: import os
       ...: import time
       ...: ret = os.fork()
       ...: 
       ...: if ret == 0:
       ...:     while True:
       ...:         print("==1==")
       ...:         time.sleep(1)
       ...: else:
       ...:     while True:
       ...:         print("==2==")
       ...:         time.sleep(1)
       ...:         
    ==2==
    ==1==
    ==2==
    ==1==
    ==2==
    ==1==
    ==2==
    ==1==
    ==2==
    ==1==
    .
    .
    .
    

      ↑用vscdoe调试出错。
      程序走到ret = os.fork(),将创建一个新进程
      程序走到ret = os.fork()这行代码,先算的是右边,计算右边的时候,程序开始一分为二。
      os.fork()会返回2个特殊值,一个大于0,表示父进程,一个等于0,为子进程。

    In [2]: import os
       ...: import time
       ...: ret = os.fork()
       ...: 
       ...: if ret == 0:
       ...:     while True:
       ...:         print("==1==")
       ...:         print(ret)
       ...:         time.sleep(1)
       ...: else:
       ...:     while True:
       ...:         print("==2==")
       ...:         print(ret)
       ...:         time.sleep(1)
       ...:         
    ==2==
    8537
    ==1==
    0
    ==2==
    8537
    ==1==
    0
    .
    .
    .
    

      ↑涉及多进程,fork()的返回值不一定。父子谁先执行也不一定。你只能确定父执行什么代码,子执行什么代码。

    • 1-2 fork创建子进程—getpid、getppid

    In [3]: 
       ...: import os
       ...: import time
       ...: ret = os.fork()
       ...: 
       ...: if ret == 0:
       ...:     while True:
       ...:         print("==1==,pid=%d,ppid=%d"%(os.getpid(),os.getppid()))
       ...:         print(ret)
       ...:         time.sleep(1)
       ...: else:
       ...:     while True:
       ...:         print("==2==,pid=%d"%os.getpid())
       ...:         print(ret)
       ...:         time.sleep(1)
       ...:         
    ==2==,pid=9464
    9525
    ==1==,pid=9525,ppid=9464
    0
    .
    .
    .
    
    In [4]: ?os.getpid()
    Signature: os.getpid()
    Docstring: Return the current process id.
    Type:      builtin_function_or_method
    
    In [5]: ?os.getppid()
    Signature: os.getppid()
    Docstring:
    Return the parent's process id.
    
    If the parent process has already exited, Windows machines will still
    return its id; others systems will return the id of the 'init' process (1).
    Type:      builtin_function_or_method
    

      ↑os.fork()返回给父进程的大于0的值,就是子进程的PID。

    • 1-3 fork创建子进程—父子的先后顺序

      使用终端调试下列代码:

    vim 1.py
    
      1 import os
      2 import time
      3 ret = os.fork()
      4 if ret==0:
      5         print("subprocess")
      6         time.sleep(1)
      7         print("subprocess over")
      8 else:
      9         print("parent process")
     10 
    
    python3 1.py
    
    li@li-ThinkPad-T420s:~$ python3 1.py
    parent process
    subprocess
    li@li-ThinkPad-T420s:~$ subprocess over
    

      ↑多进程结构中,只要主进程结束,就会出现命令提示符,就可以进行下一次操作。但是此时子进程还没有结束,所以命令行提示符出现后,子进程还会执行输出,就输出到了命令提示符后面了。同时因为默认print()有换行,此时光标会被挤到下一行。
      ↑结论:如果主进程结束了,就直接退出了,不会等子进程结束。

      1 import os
      2 import time
      3 ret = os.fork()
      4 if ret==0:
      5         print("subprocess")
      6         time.sleep(1)
      7         print("subprocess over")
      8 else:
      9         print("parent process")
     10 
     11 print("over")
    
    li@li-ThinkPad-T420s:~$ python3 1.py
    parent process
    over
    subprocess
    li@li-ThinkPad-T420s:~$ subprocess over
    over
    

      ↑“over”会被执行2次,父子各一次。
      注意点:一个进程的系统开销很大。

    • 1-4 fork创建子进程—全局变量在多进程中不共享

      1 
      2 import os
      3 import time
      4 ret = os.fork()
      5 if ret==0:
      6     while True:
      7         print("subprocess")
      8         print("subprocess")
      9         print("subprocess")
     10         time.sleep(1)
     11 else:
     12     while True:
     13         print("parent process")
     14         time.sleep(1)
    
    li@li-ThinkPad-T420s:~$ python3 3.py
    parent process
    subprocess
    subprocess
    subprocess
    parent process
    subprocess
    subprocess
    subprocess
    parent process
    subprocess
    subprocess
    subprocess
    subprocess
    parent process
    subprocess
    subprocess
    parent process
    subprocess
    subprocess
    subprocess
    subprocess
    subprocess
    subprocess
    .
    .
    .
    

      ↑父子进程执行的不确定性的单位,是可大可小的,不一定三句print("subprocess")都执行完了才会切换到print("parent process")

      1 import os
      2 import time
      3 
      4 g_n=100
      5 
      6 ret = os.fork()
      7 if ret==0:
      8         print("subprocess")
      9         g_n+=1
     10         print("sub.n=%d"%g_n)
     11 else:
     12         time.sleep(3)
     13         print("parent process")
     14         print("par.n=%d"%g_n)
    
    
    subprocess
    sub.n=101
    parent process
    par.n=100
    

      ↑创建了子进程之后,代码共享,但是数据(全局、局部)是独享,个人有一份,互不干扰。
      缺点:进程间数据不共享。如何解决?进程间通信

    • 1-5 fork创建子进程—多个fork

      1 import os
      2 import time
      3 ret = os.fork()
      4 if ret == 0:
      5     print("fork1.subprocess")
      6 
      7 else:
      8 
      9     print("fork1.parent process")
     10 
     11 ret = os.fork()
     12 if ret == 0:
     13     print("fork2.subprocess")
     14 
     15 else:
     16 
     17     print("fork2.parent process")
     18 
     19 
     20 ret = os.fork()
     21 if ret == 0:
     22     print("fork3.subprocess")
     23 
     24 else:
     25 
     26     print("fork3.subprocess")
    
    
    li@li-ThinkPad-T420s:~$ python3 5.py
    fork1.parent process
    fork1.subprocess
    fork2.parent process
    fork2.parent process
    fork2.subprocess
    fork3.subprocess
    fork3.subprocess
    fork3.subprocess
    fork3.subprocess
    fork3.subprocess
    fork2.subprocess
    fork3.subprocess
    li@li-ThinkPad-T420s:~$ fork3.subprocess
    fork3.subprocess
    

      一次fork(),1变2
      二次fork(),2变4
      三次fork(),4变8
      2+4+8=14

      如果你把第二个fork()放在某一个进程中,则本次fork只能增加一个进程。
      如果你把第二个fork()放在全局,则第一个fork()产生的2个进程,各自会再产生一个进程,总进程将变为4。

      1 import os
      2 import time
      3 print("before,%d"%os.getpid())
      4 ret = os.fork()
      5 if ret == 0:
      6     print("fork1.subprocess,%d"%os.getpid())
      7 
      8 else:
      9 
     10     print("fork1.parent process,%d"%os.getpid())
     11 
     12     ret = os.fork()
     13     if ret == 0:
     14         print("fork2.subprocess,%d"%os.getpid())
     15 
     16     else:
     17 
     18         print("fork2.parent process,%d"%os.getpid())
    
    li@li-ThinkPad-T420s:~$ python3 6.py
    before,15844
    fork1.parent process,15844
    fork1.subprocess,15845
    fork2.parent process,15844
    fork2.subprocess,15846
    

      ↑把第二个fork()放在父进程中,一共产生3个进程。
      ↓思考下例:

      1 import os
      2 
    #1变2
      3 os.fork() 
    #2变4
      4 os.fork()
    #4变8
      5 os.fork()
      6 
      7 print("------1------")
    
    ------1------
    ------1------
    ------1------
    ------1------
    li@li-ThinkPad-T420s:~$ ------1------
    ------1------
    ------1------
    ------1------
    

      ↑每调用一次,进程数乘以2
      ↓危险危险危险危险危险危险危险

    import os
    
    os.fork()
    os.fork()
    while True:
        os.fork()
    
    print("------1------")
    

      ↑fork炸弹。

    相关文章

      网友评论

          本文标题:02Python学习笔记之二.七【多任务、fork、getp(p

          本文链接:https://www.haomeiwen.com/subject/ezjjsctx.html