02Python学习笔记之二.七【多任务、fork、getp(p)id】2019-08-19

章节号 内容            
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炸弹。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容