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

2019-08-19  本文已影响0人  平知
章节号 内容            
1图片格式(png) 宽度大于620px,保持高宽比减低为620px
1-1 应用
1-1-1 方法

第1章节  多任务概念理解

  

第2章节  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()的返回值不一定。父子谁先执行也不一定。你只能确定父执行什么代码,子执行什么代码。

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。

  使用终端调试下列代码:

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 
  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 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炸弹。

上一篇下一篇

猜你喜欢

热点阅读