今日主要内容:

1.管道(Pipe) 数据接收一次就没有了

2.事件(Event)

3.基于事件的进程通信

4.信号量(Semaphore)

5. 进程池(重点)

6.进程池的同步方法和异步方法

7. 进程池的回调函数,( pool.apply_async(f1,args=(1,),callback=f2) ) ,回调函数是在异步进程中的函数

1.管道(Pipe) 数据接收一次就没有了

Pipe() #创建管道,全双工,返回管道的两端,但是一端发送消息,只能是另一端才能接受到,自己这一端是接收不到的

from multiprocessing import Process,Pipe
def f1(conn):
from_zhujincheng=conn.recv()# 此处接收可以接收任何数据,而且不需要带最大的传输的大小
print('我是子进程')
print('来自主进程的消息>>>',from_zhujincheng)

if __name__=='__main__':
conn1,conn2=Pipe() # 创建管道,全双工,返回管道的两端,但是一端发送的消息,只能另一端接收,自己这一端是不能接受的
# 可以将一端或者两端发送给其他的进程,那么多个进程之间就可以通过这一个管道进行通信了 但是这样会导致数据的不安全,容易导致程序错乱

p1=Process(target=f1,args=(conn1,) )
p1.start()
conn2.send('你好啊,大兄嘚')
print('我是主进程')

2.事件(Event)

Event() #创建事件对象,这个对象的初始状态为False

from multiprocess import Process,Event

e=Event() # 创建事件对象,这个对象的初始状态为False
print('判断e的状态>>>' , e.is_set()) #判断e当前的状态
print('程序运行到这里了')
e.set() # 这里的作用是将对象的状态改为True
e.clear() # 将e的状态改为False
e.wait() # 如果程序中e的状态为False,那么系统会阻塞在这里,只有改为True的时候才会继续往下执行
print('进程走过了wait.')

3.基于事件的进程通信
import time
from multiprocessing import Process,Event

def func(e):
time.sleep(1)
n=100
print('子进程计算结果为',n)
e.set() # 将e的值修改为True

if __name__=='__main__':
e=Event() # 创建事件对象,初始状态为False
p=Process(target=func,args=(e,))
p.start()

print('主程序在等待中......')
e.wait() # 等待e的值变为True
print('结果执行完毕,可以拿到这个值')

4.信号量(Semaphore)

S = semphore(4),内部维护了一个计数器,acquire-1,release+1,为0的时候,其他的进程都要在acquire之前等待
S.acquire()
需要锁住的代码
S.release()

Semaphore(4) # 计数器4,acquire一次减一,如果semaphore的值为0,其他人等待,release加一 . 抢票啊啥的一般用这个,就是多个程序抢占这4个cpu,如果4个都被占用了,那么他们剩余的全部等待,只有当一个人执行完毕的时候,剩下的人才会继续争抢这个cpu.

import time
import random
from multiprocessing import Process,Semaphore
def func():
s.acquire() # 与进程锁的用法类似
print(f'{i}号男嘉宾登场')
time.sleep(random.randint(1,3)) # 随机
s.release() #与进程锁的用法类似
if __name__=='__main__':
s=Semaphore(3) # 计数器3,每当acquire一次,计数器就减一,当release一次,计数器就加一. 如果计数器为0,那么意味着所有的计数器都被占用,其他的程序都要等待这3个程序,如果一个执行完毕后,剩下的才可以继续争抢这个名额.
for i in range(10): # 创建了10个进程,
p=Process(target=func,args=(i,))
p.start()

5. 进程池(重点)

进程的创建和销毁是很有消耗的,影响代码执行效率
进程池:
Map:异步提交任务,并且传参需要可迭代类型的数据,自带close和join功能
Res = Apply(f1,args=(i,)) #同步执行任务,必须等任务执行结束才能给进程池提交下一个任务,可以直接拿到返回结果res

Res_obj = Apply_async(f1,args=(i,)) #异步提交任务,可以直接拿到结果对象,从结果对象里面拿结果,要用get方法,get方法会阻塞程序,没有拿到结果会一直等待

Close : 锁住进程池,防止有其他的新的任务在提交给进程池
Join : 等待着进程池将自己里面的任务都执行完

回调函数:
Apply_async(f1,args=(i,),callback=function) #将前面f1这个任务的返回结果作为参数传给callback指定的那个function函数

进程池的map用法 (Pool)

# 对比多进程和进程池的效率,统计进程池和多进程执行100个任务的时间
import time
from multiprocessing import Process,Pool
def func(i):
time.sleep(0.5)
for a in range(10):
n=n+i

if __name__=='__main__':
# 进程池执行100个任务的时间
s_time=time.time()# 记录开始的时间
p=Pool(4) # 里面的参数是指定进程池中有多少个进程用的,4表示4个进程,如果不传参数,那么默认开启的进程数就是你电脑的cpu个数
p.map(func,range(100)) # map 2个参数第一个是你要执行的函数,第二个必须是可迭代的 ,异步提交任务,自带join功能
e_time=time.time()# 记录结束的时间
res_time=e_time-s_time
print('进程池执行命令所用时间>>>',res_time)

#多进程执行100个任务的时间
p_s_t=time.time()
p_list=[]
for i in range(100):
p=Process(target=func,args=(i,))
p.start()
p_list.append(p)

[pp.join() for pp in p_list]
p_e_t=time.time()

res_t = p_e_t - p_s_t

print('多进程执行命令所用的时间>>>',res_t)

# 结果
进程池执行命令所用时间:0.40s
多进程执行命令所用时间:9.24s
所以说进程池的时间比多进程的时间快了近十倍,所以......你懂我的意思吧,兄嘚

6.进程池的同步方法和异步方法
apply() 同步方法,将任务变成了串行
apply_async()异步方法

# 同步方法
import time
from multiprocessing import Process,Pool
def func(n):
time.sleep(1)
# print(n)
return n*n

if __name__=='__main__':
po=Pool(4)
for i in range(10):
print('你好啊,大哥')
res=po.apply(func,args=(i,)) #进程池的同步方法,将任务变成了串行
print(res)

#异步方法
import time
from multiprocessing import Process,Pool

def func():
pass

if __name__=='__main__':
po=Pool(4)
p_list=[]
for i in range(10):
print('你能每次都看到我吗?')
res=po.apply_async(func,args=(i,)) #异步给进程池提交任务
p_list.append(res)

po.close()#锁住进程池,意思就是不让其他的长须再往这个进程池里面提交任务了
po.join() # 必须等待子程序执行完毕才可以执行主程序

#打印结果,如果异步提交之后的结果对象
for i in p_list:
print(i.get())# 从对象中拿值需要用到get方法,get的效果是join的效果
# 主程序运行结束,进程池里面的任务全部停止,不会等待进程池里面的任务
print('主进程直接结束')

7. 进程池的回调函数,( pool.apply_async(f1,args=(1,),callback=f2) ) ,回调函数是在异步进程中的函数

所谓的回调函数其实指的是,在主进程中第一个函数算出的值,被回调函数把结果传入到第二个函数中进行计算.

import os
from multiprocess import Process,Pool

def func(n):
s=n+1
return s**2

def func2(x):
print('回调函数中的结果>>>',x)

if __name__=='__main__':
po=Pool(4)
po.apply_async(func,args=(3,),callback=func2)
po.close()
po.join()

print('主进程的id',os.getpid())

day32 信号量 事件 管道 进程池的更多相关文章

  1. GIL与普通互斥锁区别,死锁现象,信号量,event事件,进程池与线程池,协程

    GIL与普通互斥锁区别 GIL锁和互斥锁的异同点 相同: 都是为了解决解释器中多个线程资源竞争的问题 异: 1.互斥锁是Python代码层面的锁,解决Python程序中多线程共享资源的问题(线程数据共 ...

  2. day31 管道 进程池 数据共享

    1.    管道(了解) #创建管道的类: Pipe([duplex]):在进程之间创建一条管道,并返回元组(conn1,conn2),其中conn1,conn2表示管道两端的连接对象,强调一点:必须 ...

  3. Manager模块 队列 管道 进程池

    Manager模块 作用:  多进程共享变量. Manager的字典类型: 如果value是简单类型,比如int,可以直接赋值给共享变量,并可以后续直接修改 如果value是复杂类型 ,比如list, ...

  4. Event事件、进程池与线程池、协程

    目录 Event事件 进程池与线程池 多线程爬取梨视频 协程 协程目的 gevent TCP服务端socket套接字实现协程 Event事件 用来控制线程的执行 出现e.wait(),就会把这个线程设 ...

  5. 《python》join、守护进程、锁/信号量/事件、进程队列

    一.multiprocess.process模块 1.join方法 阻塞主进程,等待子进程执行完毕再放开阻塞 import time import random from multiprocessin ...

  6. Python之进程 3 - 进程池和multiprocess.Poll

    一.为什么要有进程池? 在程序实际处理问题过程中,忙时会有成千上万的任务需要被执行,闲时可能只有零星任务.那么在成千上万个任务需要被执行的时候,我们就需要去创建成千上万个进程么?首先,创建进程需要消耗 ...

  7. 进程同步控制(锁,信号量,事件), 进程通讯(队列和管道,生产者消费者模型) 数据共享(进程池和mutiprocess.Pool模块)

    参考博客 https://www.cnblogs.com/xiao987334176/p/9025072.html#autoid-1-1-0 进程同步(multiprocess.Lock.Semaph ...

  8. python之路--管道, 事件, 信号量, 进程池

    一 . 管道 (了解) from multiprocessing import Process, Pipe def f1(conn): # 管道的recv 里面不用写数字 from_main_proc ...

  9. python 管道 事件(Event) 信号量 进程池(map/同步/异步)回调函数

    ####################总结######################## 管道:是进程间通信的第二种方式,但是不推荐使用,因为管道会导致数据不安全的情况出现 事件:当我运行主进程的 ...

随机推荐

  1. easyUI tree 自定义图标

    文章转载自: https://blog.csdn.net/zhlantian/article/details/52913115 近期由于项目中需要使用easyui tree树形列表,并在系统中动态配置 ...

  2. vux的x-input的源码分析

    <template> <div class="vux-x-input weui-cell" :class="{'weui-cell_warn': sho ...

  3. nodejs通过request请求远程url的文件并下载到本地

    需要循环去下载远程文件,然后自己写了一个demo,可以直接运行,如下: //文件下载 var fs = require("fs"); var path = require(&quo ...

  4. CURL操作

    具体代码如下: <?php$curl=curl_init(); //初始化$url='http://www.ecshop.com';//curl_setopt(curl资源,选项标志,选项值)c ...

  5. Cisco 设备设置监控口

    > enable                 # 从用户模式进入特权模式# show ip int bri     # 查看当前所有端口状态 # conf t                ...

  6. WCF利用Stream上传大文件

    WCF利用Stream上传大文件 转自别人的文章,学习这个例子,基本上wcf也算入门了,接口用法.系统配置都有了 本文展示了在asp.net中利用wcf的stream方式传输大文件,解决了大文件上传问 ...

  7. C#如何实现类似QQ那样靠边隐藏的功能

    http://www.cnblogs.com/yechensi/archive/2009/08/02/1537145.html C#如何实现类似QQ那样靠边隐藏的功能 你想过为自己的程序添加靠边隐藏的 ...

  8. caffe-ssd

    1.安装依赖 1 sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libhdf5-ser ...

  9. 集合 (set)

    set 是一个无序不重复的元素集,集合跟字典是无序的,不支持索引 创建集合: 第一种方式:通过{ }创建 >>> num={1,2,3,4,3,3,1} >>> n ...

  10. Linux 文本编辑器 vim

    第五讲 文本编辑器 vim