进程

Process(target,name,args,kwargs)

p.pid : 创建的新的进程的PID号
p.is_alive() 判断进程是否处于alive状态

p.daemon = True 默认为False 如果设置为True 则一般不需要加join,并且主进程退出时子进程也会结束

* daemon 属性设置要在start() 前

注意:
如果多个子进程拷贝同一个父进程中的对象,则多个子进程使用的是同一个对象
(如文件对象,套接字,队列,管道。。。)
如果是在创建子进程后单独创建的对象,则多个子进程各不相同

 from multiprocessing import Process
 from time import sleep
 import os 

 def th1():
     sleep(3)
     print("吃饭")
     print(os.getpid(),'---',os.getppid())   # 当前进程的PID号,父进程的PID号
 def th2():
     sleep(4)
     print("睡觉")
     print(os.getpid(),'---',os.getppid())
 def th3():
     sleep(2)
     print("打豆豆")
     print(os.getpid(),'---',os.getppid())

 things = [th1,th2,th3]
 process = []

 for th in things:
     p = Process(target = th)
     process.append(p)  #保存进程对象
     p.start()

 #回收进程
 for i in process:
     i.join()

 # 打豆豆
 # 5625 --- 5622
 # 吃饭
 # 5623 --- 5622
 # 睡觉
 # 5624 --- 5622
 from multiprocessing import Process
 from time import sleep

 def worker(sec,name):
     for i in range(3):
         sleep(sec)
         print("I'm %s"%name)
         print("I'm working...")

 p = Process(target = worker,name = "Worker",args = (2,),kwargs = {'name':'Alex'})
 p.start()

 print(p.name)   # Worker
 print("Child PID:",p.pid) # 创建新进程的PID号
 print("is alive?  ",p.is_alive()) # 判断进程状态

 p.join()
 print("is alive?  ",p.is_alive())   # False

 # Worker
 # Child PID: 5994
 # is alive?   True
 # I'm Alex
 # I'm working...
 # I'm Alex
 # I'm working...
 # I'm Alex
 # I'm working...
 # is alive?   False
 from multiprocessing import Process
 from time import sleep,ctime 

 def tm1():
     while True:
         sleep(2)
         print(ctime())

 p = Process(target = tm1)
 p.daemon = True
 p.start()
 sleep(3)
 print("main process over")

 # Wed Aug 15 11:08:28 2018
 # main process over

p.daemon = True

创建自定义进程类

1. 编写类继承Process
2. 在自定义类中加载父类__init__以获取父类属性,同时可以自定义新的属性
3. 重写run方法,在调用start时自动执行该方法

进程的缺点:进程在创建和销毁的过程中消耗的资源相对较多

 from multiprocessing import Process
 import time 

 class ClockProcess(Process):
     def __init__(self,value):
         #调用父类init
         super().__init__()
         self.value = value
     #重写run方法
     def run(self):
         for i in range(5):
             time.sleep(self.value)
             print("The time is {}".format(time.ctime()))

 p = ClockProcess(2)
 #自动执行run
 p.start()

 p.join()

 # The time is Wed Aug 15 12:32:54 2018
 # The time is Wed Aug 15 12:32:56 2018
 # The time is Wed Aug 15 12:32:58 2018
 # The time is Wed Aug 15 12:33:00 2018
 # The time is Wed Aug 15 12:33:02 2018

自定义进程类

进程池技术

产生原因 : 如果有大量的任务需要多进程完成,而任务周期又比较短且需要频繁创建。此时可能产生大量进程频繁创建销毁的情况,消耗计算机资源较大

使用方法
1. 创建进程池,在池内放入适当数量的进程
2. 将事件封装函数,放入到进程池
3. 事件不断运行,知道所有放入进程池事件运行完成
4. 关闭进程池,回收进程

from multiprocessing import Pool

Pool(processes)  创建进程池对象
参数:进程数量
返回 : 进程池对象

pool.apply_async(fun,args,kwds)  将事件放入进程池执行
参数: fun 要执行的事件函数
args 以元组为fun传参
kwds 以字典为fun传参
返回值 : 返回一个事件对象 通过get()属性函数可以获取fun的返回值

pool.apply(fun,args,kwds)  将事件放入进程池执行

参数: fun 要执行的事件函数
args 以元组为fun传参
kwds 以字典为fun传参

pool.close()  关闭进程池,无法再加入事件

pool.join()  回收进程池

 from multiprocessing import Pool
 from time import sleep,ctime 

 def worker(msg):
     sleep(2)
     print(msg)
     return ctime()

 pool = Pool(processes = 4)  #创建进程池对象

 result = []
 for i in range(10):
     msg = "hello %d"%i
     r = pool.apply_async(func = worker,args = (msg,))   #将事件放入进程池
     result.append(r)
     # pool.apply(func = worker,args = (msg,))   #同步执行

 pool.close()    #关闭进程池
 pool.join() #回收
 for i in result:    #获取事件函数返回值
     print(i.get())

 # hello 3
 # hello 1
 # hello 2
 # hello 0
 # hello 4
 # hello 7
 # hello 5
 # hello 6
 # hello 9
 # hello 8
 # Wed Aug 15 11:52:01 2018
 # Wed Aug 15 11:52:01 2018
 # Wed Aug 15 11:52:01 2018
 # Wed Aug 15 11:52:01 2018
 # Wed Aug 15 11:52:03 2018
 # Wed Aug 15 11:52:03 2018
 # Wed Aug 15 11:52:03 2018
 # Wed Aug 15 11:52:03 2018
 # Wed Aug 15 11:52:05 2018
 # Wed Aug 15 11:52:05 2018

pool(process)

pool.map(func,iter)  将要执行的事件放入到进程池
参数 : func 要执行的函数
iter 迭代对象,给func传参
返回值 : 返回 func的返回值列

 from multiprocessing import Pool
 import time 

 def fun(n):
     time.sleep(1)
     print("执行 pool map事件",n)
     return n ** 2 

 pool = Pool(4)
 r = pool.map(fun,range(6))  # 在进程池放入6个事件
 print("返回值列表:",r)

 pool.close()
 pool.join()

 # 执行 pool map事件 0
 # 执行 pool map事件 3
 # 执行 pool map事件 1
 # 执行 pool map事件 2
 # 执行 pool map事件 4
 # 执行 pool map事件 5
 # 返回值列表: [0, 1, 4, 9, 16, 25]

pool.map(func,iter)

进程间通信(IPC)

由于进程间空间独立,资源无法共享,此时在进程间通信就需要专门的通信方法。

进程间通信方法 : 管道 消息队列 共享内存 信号
信号量 套接字

管道通信

  管道:在内存中开辟一段空间,形成管道结构,多进程使用同一个管道,进程可以对管道进行读写操作

multiprocess ---> Pipe

fd1,fd2 = Pipe(duplex = True)

功能:创建一个管道

参数:默认为双向管道,如果设置为False,则为单向管道

返回值:如果双向管道,fd1,fd2 都可以进行读写操作;如果是单向管道,则fd1只可读,fd2只可写。

fd.recv()

功能;从管道读取内容2

返回值:读到的内容

  # 当管道为空则阻塞

fd.send(data)

功能:向管道写入内容

参数:要发送的内容

  # 管道满是会阻塞,几乎可以发送所有python支持的数据

 from multiprocessing import Process,Pipe
 import os,time 

 fd1,fd2 = Pipe(False)   #创建管道

 def fun(name):
     time.sleep(3)

     fd2.send({'a':1,'b':2}) #向管道写入内容

 jobs = []
 for i in range(5):
     p = Process(target = fun,args = (i,))
     jobs.append(p)
     p.start()
 for i in range(5):

     data = fd1.recv()   #读取管道
     print(data)

 for i in jobs:
     i.join()

 # {'b': 2, 'a': 1}
 # {'b': 2, 'a': 1}
 # {'b': 2, 'a': 1}
 # {'b': 2, 'a': 1}
 # {'b': 2, 'a': 1}

fd1,fd2 = Pipe(False)

消息队列

队列:先进先出

从内存中开辟队列结构空间,多个进程可以向队列投放消息,在取出来的时候按照存入顺序取出

创建队列

q = Queue(maxsize = 0)  创建队列对象
参数 : maxsize : 默认表示系统自动分配队列空间
如果传入正整数则表示最多存放多少条消息
返回值 : 队列对象

q.put(data,[block,timeout])  向队列中存入消息

参数:data 存放消息(python数据类型)

  block  默认为True表示当前队列满的时候阻塞,设置为False则表示非阻塞

  timeout  blockTrue表示超时时间

返回值:返回获取的消息

q.full()  判断队列是否为满

q.empty()  判断队列是否为空

q.qsize()  判断当前队列有多少消息

q.close()  关闭队列

 from multiprocessing import Queue
 from time import sleep 

 q = Queue(3)    # 创建队列

 q.put(1)
 sleep(0.1)
 print(q.empty())
 q.put("Process Queue")
 q.put([1,2,3])
 print(q.full())
 #如设置为非阻塞则产生Full异常
 # q.put(666,False) #非阻塞
 # q.put(666,True,3)  #超时
 print(q.get())
 print(q.qsize()) #查看消息数量
 q.close()

 # False
 # True

q = Queue(3)

 from multiprocessing import Process,Queue
 import time 

 #创建队列
 q = Queue()

 def fun1():
     time.sleep(1)
     q.put({'})

 def fun2():
     print("收到消息:",q.get())

 p1 = Process(target = fun1)
 p2 = Process(target = fun2)
 p1.start()
 p2.start()
 p1.join()
 p2.join()

 # 收到消息: {'name': 'Abby', 'passwd': '123'}

queue

共享内存

在内存中开辟一段空间,存储数据,对多个进程可见,每次写入共享内存中的数据会覆盖之前的内容

from multiprocessing import Value

obj = Value(ctype,obj)

功能:开辟共享内存空间

参数:ctype  字符串  要转变的c的数据类型,对比类型对照表

  obj  共享内存的初始化数据

返回:共享内存对象

obj = Array(ctype,obj)

功能:开辟共享内存

参数:ctype  要转化的c的类型

  obj  要存入共享的数据

    如果是列表  将列表存入共享内存,要求数据类型一致

    如果是正整数  表示开辟几个数据空间

 from  multiprocessing import Process,Value
 import time
 import random  

 #创建共享内存
 money = Value('i',6000)

 #存钱
 def deposite():
     for i in range(100):
         time.sleep(0.05)
         #对value的修改就是对共享内存的修改
         money.value += random.randint(1,200)
 #花销
 def withdraw():
     for i in range(100):
         time.sleep(0.04)
         #对value的修改就是对共享内存的修改
         money.value -= random.randint(1,200)

 d = Process(target = deposite)
 w = Process(target = withdraw)

 d.start()
 w.start()

 d.join()
 w.join()
 print(money.value)

obj = Value(ctype,obj)

       管道        消息队列    共享内存

开辟空间   内存         内存      内存

读写方式 两端读写(双向/单向)   先进先出    操作覆盖

效率    一般         一般      较快

应用   多用于父子进程    使用广泛   复杂、需要同步互斥操作    通信

cookie
获取文件大小
size = os.path.getsize("./timg.jpeg")

  

pythonNetday06的更多相关文章

  1. python学习菜单

    一.python简介 二.python字符串 三.列表 四.集合.元组.字典 五.函数 六.python 模块 七.python 高阶函数 八.python 装饰器 九.python 迭代器与生成器  ...

随机推荐

  1. 图像添加logo水印函数

    <?php //图像添加水印函数 /** *为一张图片添加上一个logo水印(以保存新图片的方式实现) *@param string $picname 被缩放的处理图片源 *@param int ...

  2. redis事务和脚本

    事务,简单理解就是,一组动作,要么全部执行,要么就全部不执行.从而避免出现数据不一致的情况. redis提供了简单的事务功能,将一组需要的命令放到multi和exec两个命令之间.multi代表事务开 ...

  3. 国内maven库镜像(阿里云)

    我觉得fuck GFW(Great FireWall) 真是阻碍国内技术发展罪大恶极的东西.各种不方便,各种落后,各种闭塞. anyway,maven中央仓库,本来有oschina的可以用,现在关了. ...

  4. 【Android】冷门常用 ADB

    清除应用缓存adb shell pm clear 包名 获取手机中安装的包名,加上部分包名可以做筛选 adb shell pm list package adb shell pm list packa ...

  5. 利用JavaScript将页面截图生成图片传给后台的插件:html2canvas

    利用JavaScript将页面截图生成图片传给后台的插件:html2canvas 一.总结 一句话总结: 10 <script type="text/javascript"& ...

  6. 递归--练习3--noi7592求最大公约数问题

    递归--练习3--noi7592求最大公约数问题 一.心得 两个低级错误:1. ll setMax(ll &m,ll &n)中无引用,结果只传值,没传地址2. return f(n,m ...

  7. VM虚拟机安装的XP如何全屏

    首先安装install VMwear Tools..,如图:

  8. java 8 日期api

    //localdatetime -> string LocalDateTime now = LocalDateTime.now(); String format = now.format(Dat ...

  9. BZOJ2958 序列染色

    果然清华集训的题目...显然的DP题但是不会做... 我们令f[i][j][w]表示状态方程 w表示到了字符串的第w个 i = 0, 1, 2分别表示k个B和k个W都没填上.k个B填上了k个W没填上. ...

  10. [CSS布局]3列布局:左右两列固定宽度、中间列自适应满宽

    一种常见的3列布局,左右两列固定宽度.中间列自适应满宽.整个网页不出现横向滚动条 纯CSS实现 效果图: 代码: <!DOCTYPE html> <html lang="e ...