02Python学习笔记之二.八【process、进程池、进程间通信】2019-08-19

章节号 内容            
1图片格式(png) 宽度大于620px,保持高宽比减低为620px
12 123
1-1-1 方法
1-1-1 方法

第1章节  Process

  • 1-1 Process—使用

  因为fork()在windows系统中无法使用,于是python为了兼容和跨平台,使用multiprocessing来实现。具体为使用Process类。

  1 from multiprocessing import Process
  2 import os
  3 import time
  4 
  5 print("Before Process,pid=%d" % os.getpid())
  6 
  7 
  8 def test():
  9     while True:
 10         print("subprocess,test")
 11         time.sleep(1)
 12 
 13 
 14 p = Process(target=test)
 15 p.start()
 16 
 17 while True:
 18     print("--parent process")
 19     time.sleep(1)

  1、使用Process类创建一个对象,这个对象相当于一个进程。
  2、对象p.start()则开始执行这个进程。
  3、这个进程要执行的代码,放到一个函数test()中,然后在生成Process对象的时候,以参数方式传入Process()。
  4、一旦函数test()的代码执行完毕,这个进程就相当于终止,因此一般为一个死循环。
  5、子进程进入函数,主进程继续往下走。

li@li-ThinkPad-T420s:~$ python3 9.py
Before Process,pid=17945
--parent process
subprocess,test
--parent process
subprocess,test
--parent process
subprocess,test
--parent process
subprocess,test
--parent process
subprocess,test

  ↑以后写代码,扔掉fork!

  • 1-2 Process—主进程等待子进程结束

  ↓和fork()的不同:

  1 from multiprocessing import Process
  2 import os
  3 import time
  4 
  5 print("Before Process,pid=%d" % os.getpid())
  6 
  7 
  8 def test():
  9     print("Sub Process,pid=%d" % os.getpid())
 10     while True:
 11         print("subprocess,test")
 12         time.sleep(1)
 13 
 14 
 15 p = Process(target=test)
 16 p.start()
li@li-ThinkPad-T420s:~$ python3 10.py 
Before Process,pid=18202
Sub Process,pid=18203
subprocess,test
subprocess,test
subprocess,test
subprocess,test
subprocess,test
subprocess,test
subprocess,test
subprocess,test
.
.
.

  ↑这里我们删掉了主进程的循环代码,从代码上看主进程已经结束,但是主进程其实并没有关闭。
  主进程:等待所有子进程结束,自己才结束。
  ↑和fork()的区别

  1 from multiprocessing import Process
  2 import os
  3 import time
  4 
  5 print("Before Process,pid=%d" % os.getpid())
  6 
  7 
  8 def test():
  9     print("Sub Process,pid=%d" % os.getpid())
 10 #    while True:
 11     for i in range(5):
 12         print("subprocess,test")
 13         time.sleep(1)
 14 
 15 
 16 p = Process(target=test)
 17 p.start()
li@li-ThinkPad-T420s:~$ python3 10.py 
Before Process,pid=18827
Sub Process,pid=18828
subprocess,test
subprocess,test
subprocess,test
subprocess,test
subprocess,test
li@li-ThinkPad-T420s:~$ 

  ↑等待了子进程结束。子进程循环5次。

  • 1-3 Process—Process类的常用方法(截断,待学习补充)

  is_alive()
  run()
  terminate()
  join([timeout])方法,timeout为等待多少秒。带[]中括号的东西,可写可不写。
  ↓子进程运行次数在1到5之间,不确定

  1 from multiprocessing import Process
  2 import os
  3 import time
  4 import random
  5 
  6 print("Before Process,pid=%d" % os.getpid())
  7 
  8 
  9 def test():
 10     for i in range(random.randint(1, 5)):
 11 
 12         print("subprocess,test")
 13         time.sleep(1)
 14 
 15 
 16 p = Process(target=test)
 17 p.start()
 18 
 19 p.join()
 20 print("----parent----")
li@li-ThinkPad-T420s:~$ python3 11.py
Before Process,pid=18939
subprocess,test
subprocess,test
subprocess,test
----parent----

  程序执行到join() (堵塞)就停止,一直等子进程执行完毕,才往下走。

  • 1-4 Process—子类创建子进程

  1 from multiprocessing import Process
  2 import os
  3 import time
  4 import random
  5 
  6 
  7 class pclass(Process):
  8     def __init__(self, interval):
  9         Process.__init__(self)
 10         self.interval = interval
 11 
 12 #run方法怎么写,自进程如何执行
 13     def run(self):
 14         for i in range(random.randint(1, 5)):
 15 
 16             print("subprocess,test")
 17         time.sleep(self.interval)
 18         pass
 19 
 20 print("parent process id=%d"%os.getpid())
 21 p = pclass(1)
 22 p.start()
#start() 方法一定调用run()方法

li@li-ThinkPad-T420s:~$ python3 12.py 
parent process id=22113
subprocess,test
subprocess,test
subprocess,test
subprocess,test
  • 1-5 Process—进程池

  一来就创建进程,你用不用我不管。

  1 
  2 from multiprocessing import Pool
  3 import os
  4 import time
  5 import random
  6 
  7 
  8 def work(num):
  9     for i in range(2):
 10         print("pid=%d,num=%d" %( os.getpid(),num))
 11         time.sleep(1)
 12 
 13 po = Pool(3)
 14 
 15 for i in range(10):
 16     print("------%d-----"%(i+1))
 17     po.apply_async(work,(i,))
 18 
 19 #主进程结束了,这里要挺住
 20 po.close()
 21 po.join()

  ↑1、引入Pool类
   2、使用Pool(n)来创建一个含有n个进程的进程池。
   3、po.apply_async(函数名,(i,))来添加任务。
   4、po.close()关闭进程池,相当于不能再添加任务了。
   5、po.join()阻塞等待?否则程序直接结束了,不会有输出。
   6、任务数大于进程数,不会添加不进去。添加进去的任务,如果还没有被执行,就会等待进程来执行它。

li@li-ThinkPad-T420s:~$ python3 13.pool.py 
------1-----
------2-----
------3-----
------4-----
------5-----
------6-----
------7-----
------8-----
------9-----
------10-----
pid=23083,num=0
pid=23084,num=1
pid=23085,num=2
pid=23084,num=1
pid=23085,num=2
pid=23083,num=0
pid=23084,num=3
pid=23085,num=4
pid=23083,num=5
pid=23084,num=3
pid=23085,num=4
pid=23083,num=5
pid=23084,num=6
pid=23083,num=7
pid=23085,num=8
pid=23084,num=6
pid=23083,num=7
pid=23085,num=8
pid=23085,num=9
pid=23085,num=9

  ↑10个任务,3个进程。
  0,1,2号任务先被进程拿走,开始输出。前6个输出应该就是0或1或2。

  • 1-6 Process—多种方式对比

  1、os.fork()
    太过底层,win不支持,不要用。
  2、Process(target=xxx)
    主进程也可以做事,子进程做事。
  3、Pool(n)子进程不是越多越好。
  Pool.apply_async(xxxx)
    主进程等待,进程池做事

  • 1-7 Process—apple堵塞式添加任务

  1 
  2 from multiprocessing import Pool
  3 import os
  4 import time
  5 import random
  6 
  7 
  8 def work(num):
  9     for i in range(2):
 10         print("pid=%d,num=%d" %( os.getpid(),num))
 11         time.sleep(1)
 12 
 13 po = Pool(3)
 14 
 15 for i in range(10):
 16     print("------%d-----"%(i+1))
 17     po.apply(work,(i,))
 18 #主进程结束了,这里要挺住
 19 po.close()
 20 po.join()
li@li-ThinkPad-T420s:~$ python3 14.py
------1-----
pid=24817,num=0
pid=24817,num=0
------2-----
pid=24818,num=1
pid=24818,num=1
------3-----
pid=24819,num=2
pid=24819,num=2
------4-----
pid=24817,num=3
pid=24817,num=3
------5-----
pid=24818,num=4
pid=24818,num=4
------6-----
pid=24819,num=5
pid=24819,num=5
------7-----
pid=24817,num=6
pid=24817,num=6
------8-----
pid=24818,num=7
pid=24818,num=7
------9-----
pid=24819,num=8
pid=24819,num=8
------10-----
pid=24817,num=9
pid=24817,num=9

  ↑添加一个任务,执行一个任务,执行完了才添加下一个任务。这个方式就达不到多任务的目的。
  ↑几乎不用。

  • 1-8 Process—进程间通信

  1、引入Queue类

In [12]: from multiprocessing import Queue
    ...: 
#初始化一个Queue对象,最多可接收三条put消息
In [13]: q=Queue(3)

In [14]: q.put("msg1")

In [15]: q.full()
Out[15]: False

In [16]: q.qsize()
Out[16]: 1

In [17]: q.put("msg2")

In [18]: q.get()
Out[18]: 'msg1'

In [19]: q.empty()
Out[19]: False

In [20]: q.get()
Out[20]: 'msg2'

#没东西了,就堵塞了,Ctrl+C结束。
In [21]: q.get()
^C---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-21-4afd527a82ad> in <module>()
----> 1 q.get()

/usr/lib/python3.6/multiprocessing/queues.py in get(self, block, timeout)

#不堵塞的get,提示报错。使用这个要放在try里面。
In [22]: q.get_nowait()
---------------------------------------------------------------------------
Empty                                     Traceback (most recent call last)
<ipython-input-22-aad002f32be5> in <module>()
----> 1 q.get_nowait()

/usr/lib/python3.6/multiprocessing/queues.py in get_nowait(self)
    124 
    125     def get_nowait(self):
--> 126         return self.get(False)
    127 
    128     def put_nowait(self, obj):

/usr/lib/python3.6/multiprocessing/queues.py in get(self, block, timeout)
    105                         raise Empty
    106                 elif not self._poll():
--> 107                     raise Empty
    108                 res = self._recv_bytes()
    109                 self._sem.release()

Empty: 


  ↑put()和get()都是堵塞的,一旦放不进或者拿不出都需要验证,否则出错。q.get_nowait()放在try块中。q.put_nowait()道理类似。

In [23]: q.put([])

In [24]: q.put({})

In [25]: q.put(())

  ↑put()类型不限。
  ↓具体应用:

In [2]: ?pw.join()
Signature: pw.join(timeout=None)
Docstring: Wait until child process terminates
File:      /usr/lib/python3.6/multiprocessing/process.py
Type:      method
In [1]: 
   ...: def wr(q):
   ...:     for v in ['a','b','c']:
   ...:         print("put %s to queue"%v)
   ...:         q.put(v)
   ...:         time.sleep(random.random())
   ...: 
   ...: def rd(q):
   ...:     while True:
   ...:         if not q.empty():
   ...:             v=q.get(True)
   ...:             print("get %s from queue"%v)
   ...:             time.sleep(random.random())
   ...:         else:
   ...:             break
   ...: 
   ...: q=Queue()
   ...: pw=Process(target=wr,args=(q,))
   ...: pr=Process(target=rd,args=(q,))
   ...: 
   ...: pw.start()
        #join()等待pw结束
   ...: pw.join()
   ...: pr.start()
   ...: pr.join()
   ...: 
put a to queue
put b to queue
put c to queue
get a from queue
get b from queue
get c from queue

  ↑多个进程间通信,两两之间搭好管道

  ↓进程池中的Queue

In [7]: from multiprocessing import Manager
   ...: from multiprocessing import Pool
   ...: import os,time,random
   ...: 
   ...: def rd(q):
   ...:     for i in range(q.qsize()):
   ...:         print("读到的消息:%s"%q.get(True))
   ...:         time.sleep(random.random())   
   ...: 
   ...: def wr(q):
   ...:     for v in ['a','b','c']:
   ...:         print("写入的消息:%s"%v)
   ...:         q.put(v)
   ...:         time.sleep(random.random())    
   ...:     
   ...:     
   ...: q=Manager().Queue()#使用manager中的queue来初始化
   ...: po=Pool()
   ...: po.apply(wr,(q,))#使用阻塞方式创建进程,不需要再rd中使用死循环
   ...: po.apply(rd,(q,))
   ...: po.close()
   ...: po.join()
   ...: 
写入的消息:a
写入的消息:b
写入的消息:c
读到的消息:a
读到的消息:b
读到的消息:c

  • 1-9 Process—多进程拷贝文件

  1、创建文件夹。使用os.mkdir("copyfile")

In [8]: ls
10.py  13.pool.py  4.py  8.py      Documents/  Pictures/     test.py   Videos/
11.py  14.py       5.py  9.py      Downloads/  Public/       test.pyc
123/   1.py        6.py  ccode/    home/       __pycache__/  text.py
12.py  3.py        7.py  Desktop/  Music/      Templates/    text.pyc

In [9]: pwd
Out[9]: '/home/li'

In [10]: import os

In [11]: os.mkdir("copyfile")

In [12]: ls
10.py       14.py  6.py    copyfile/   Music/        test.py
11.py       1.py   7.py    Desktop/    Pictures/     test.pyc
123/        3.py   8.py    Documents/  Public/       text.py
12.py       4.py   9.py    Downloads/  __pycache__/  text.pyc
13.pool.py  5.py   ccode/  home/       Templates/    Videos/

  删除文件夹。使用os.rmdir("copyfile")

In [13]: os.rmdir("copyfile")

In [14]: ls
10.py  13.pool.py  4.py  8.py      Documents/  Pictures/     test.py   Videos/
11.py  14.py       5.py  9.py      Downloads/  Public/       test.pyc
123/   1.py        6.py  ccode/    home/       __pycache__/  text.py
12.py  3.py        7.py  Desktop/  Music/      Templates/    text.pyc

  获取文件夹中文件名字。使用os.listdir()

In [18]: ?os.listdir
Signature: os.listdir(path=None)
Docstring:
Return a list containing the names of the files in the directory.

path can be specified as either str, bytes, or a path-like object.  If path is bytes,
  the filenames returned will also be bytes; in all other circumstances
  the filenames returned will be str.
If path is None, uses the path='.'.
On some platforms, path may also be specified as an open file descriptor;\
  the file descriptor must refer to a directory.
  If this functionality is unavailable, using it raises NotImplementedError.

The list is in arbitrary order.  It does not include the special
entries '.' and '..' even if they are present in the directory.
Type:      builtin_function_or_method
In [20]: os.listdir()
Out[20]: 
['11.py',
 '123',
 '.presage',
 'test.pyc',
 '.local',
 'test.py',
 '3.py',
 '.shutter',
 '.6.py.swp',
 'Desktop',
 '.hidden',
 '.gconf',
 '.viminfo.tmp',
 'text.py',
 '.gnome2',
 '.config',
 '10.py',
 '.viminfo',
 '14.py',
.
.
.

  ↓从路径中分离出文件夹名之方式1

In [54]: pwd
Out[54]: '/home/li'

In [55]: a
Out[55]: '/home/li'

In [56]: a[((a.rfind('/'))+1):]
Out[56]: 'li'

  ↓从路径中分离出文件夹名之方式2

In [55]: a
Out[55]: '/home/li'

In [57]: import os

In [58]: os.path.split(a)
Out[58]: ('/home', 'li')
In [65]: a='/home/li/123'

In [66]: a
Out[66]: '/home/li/123'

In [67]: os.path.split(a)
Out[67]: ('/home/li', '123')

In [68]: os.path.split(a)[1]
Out[68]: '123'

  ↑↓类的基本结构:



  ↑↓类的基本结构:

  • 1-1 类的初步—定义一个类并创建对象实例

  1-1-1. 导言—用户管理—用户的分类及介绍
  • 1-2 类的初步—定义一个类并创建对象实例

  1-2-1. 导言—用户管理—用户的分类及介绍

第2章节 

  • 2-1 类的初步—定义一个类并创建对象实例

  2-1-1. 导言—用户管理—用户的分类及介绍
  • 2-2 类的初步—定义一个类并创建对象实例

  2-2-1. 导言—用户管理—用户的分类及介绍

第3章节 

  • 3-1 类的初步—定义一个类并创建对象实例

  3-1-1. 导言—用户管理—用户的分类及介绍
  • 3-2 类的初步—定义一个类并创建对象实例

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

推荐阅读更多精彩内容

  • 1.内存的页面置换算法 (1)最佳置换算法(OPT)(理想置换算法):从主存中移出永远不再需要的页面;如无这样的...
    杰伦哎呦哎呦阅读 3,207评论 1 9
  • 进程 操作系统背景知识 顾名思义,进程即正在执行的一个过程。进程是对正在运行程序的一个抽象。 进程的概念起源于操作...
    go以恒阅读 931评论 0 2
  • 一. 操作系统概念 操作系统位于底层硬件与应用软件之间的一层.工作方式: 向下管理硬件,向上提供接口.操作系统进行...
    月亮是我踢弯得阅读 5,944评论 3 28
  • 一. 什么是多进程? 多进程就是多个进程的意思,那么什么是进程呢? 当一个应用在开始运行时,系统会为它创建一个进程...
    酱拌饭阅读 840评论 0 5
  • 必备的理论基础 1.操作系统作用: 隐藏丑陋复杂的硬件接口,提供良好的抽象接口。 管理调度进程,并将多个进程对硬件...
    drfung阅读 3,517评论 0 5