python并发编程之进程2(管道,事件,信号量,进程池)
管道
Conn1,conn2 = Pipe()
Conn1.recv()
Conn1.send()
数据接收一次就没有了
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=(conn2,))
p1.start()
conn1.send('出来吧')
print('主进程')
事件
E = Event() #初识状态是false
E.wait() 当事件对象e的状态为false的时候,在wait的地方会阻塞程序,当对象状态为true的时候,直接在这个wait地方继续往下执行
E.set() 将事件对象的状态改为true,
E.is_set() 查看状态
E.clear() 将事件对象的状态改为false
from multiprocessing import Process,Event e = Event() #创建事件对象,这个对象的初识状态为False
print('e的状态是:',e.is_set()) # False print('进程运行到这里了')
e.set() #将e的状态改为True
print('e的状态是:',e.is_set()) # True e.clear() #将e的状态改为False e.wait() #e这个事件对象如果值为False,就在我加wait的地方等待 print('进程过了wait')
信号量
S = semphore(数字),内部维护了一个计数器,acquire-1,release+1,为0的时候,其他的进程都要在acquire之前等待
S.acquire()
需要锁住的代码
S.release()
import time,random
from multiprocessing import Process,Semaphore def f1(i,s):
s.acquire()
print('%s男嘉宾到了'%i)
time.sleep(random.randint(1,3))
s.release() if __name__ == '__main__':
s = Semaphore(4) #计数器4,acquire一次减一,为0 ,其他人等待,release加1
for i in range(10):
p = Process(target=f1,args=(i,s))
p.start()
进程池
进程的创建和销毁是很有消耗的,影响代码执行效率
在有进程池的代码中,主进程运行结束,进程池里面的任务全部停止,不会等待进程池里面的任务
pl = Pool(数字) 这个数字一般是电脑的cpu数
pl的方法:
Map:异步提交任务,并且传参需要可迭代类型的数据,自带close和join功能
import time
from multiprocessing import Process,Pool #对比多进程和进程池的效率
def f1(n):
for i in range(5):
n = n + i if __name__ == '__main__': #统计进程池执行100个任务的时间
s_time = time.time()
pool = Pool(4)
pool.map(f1,range(100))
e_time = time.time()
dif_time = e_time - s_time #统计100个进程,来执行100个任务的执行时间
p_s_t = time.time() #多进程起始时间
p_list = []
for i in range(100):
p = Process(target=f1,args=(i,))
p.start()
p_list.append(p)
[pp.join() for pp in p_list]
p_e_t = time.time()
p_dif_t = p_e_t - p_s_t
print('进程池的时间:',dif_time)
print('多进程的执行时间:',p_dif_t)
# 结果: 进程池的时间: 0.40102291107177734 多进程的执行时间: 9.247529029846191
# 可以看出进程池运行效率远远大于创建多进程
Close : 锁住进程池,防止有其他的新的任务在提交给进程池
Join : 等待着进程池将自己里面的任务都执行完
Res = Apply(f1,args=(i,)) #同步执行任务,必须等任务执行结束才能给进程池提交下一个任务,可以直接拿到返回结果res
import time
from multiprocessing import Process,Pool def f1(n):
time.sleep(1)
return n*n if __name__ == '__main__': pool = Pool(4)
for i in range(10):
res = pool.apply(f1,args=(i,))
print(res)
Res_obj = Apply_async(f1,args=(i,)) #异步提交任务,可以直接拿到结果对象,从结果对象里面拿结果,要用get方法,get方法会阻塞程序,没有拿到结果会一直等待
import time
from multiprocessing import Process,Pool def f1(n):
time.sleep(0.5)
return n*n if __name__ == '__main__': pool = Pool(4) res_list = []
for i in range(10):
res = pool.apply_async(f1,args=(i,)) # 不能直接打印返回值,因为直接返回结果对象,进程还没执行完,结果对象里没有数据
res_list.append(res) pool.close()
pool.join() #打印结果,异步提交之后的结果对象
for i in res_list:
print(i.get())
回调函数:
Apply_async(f1,args=(i,),callback=function) #将前面f1这个任务的返回结果作为参数传给callback指定的那个function函数
import os
from multiprocessing import Pool,Process def f1(n):
print('传入的函数',n)
return n*n def call_back_func(asdf):
print('回调函数',asdf) if __name__ == '__main__':
pool = Pool(4)
res = pool.apply_async(f1,args=(5,),callback=call_back_func)
pool.close()
pool.join()
python并发编程之进程2(管道,事件,信号量,进程池)的更多相关文章
- python并发编程之多进程(三):共享数据&进程池
一,共享数据 展望未来,基于消息传递的并发编程是大势所趋 即便是使用线程,推荐做法也是将程序设计为大量独立的线程集合 通过消息队列交换数据.这样极大地减少了对使用锁定和其他同步手段的需求, 还可以扩展 ...
- python并发编程之多进程1-----------互斥锁与进程间的通信
一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...
- python并发编程之多进程2-------------数据共享及进程池和回调函数
一.数据共享 1.进程间的通信应该尽量避免共享数据的方式 2.进程间的数据是独立的,可以借助队列或管道实现通信,二者都是基于消息传递的. 虽然进程间数据独立,但可以用过Manager实现数据共享,事实 ...
- python之管道, 事件, 信号量, 进程池
管道:双向通信 2个进程之间相互通信 from multiprocessing import Process, Pipe def f1(conn): from_zjc_msg = conn.recv( ...
- python并发编程之多进程1--(互斥锁与进程间的通信)
一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...
- python并发编程之多进程1互斥锁与进程间的通信
一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...
- Python 并发编程(管道,事件,信号量,进程池)
管道 Conn1,conn2 = Pipe() Conn1.recv() Conn1.send() 数据接收一次就没有了 from multiprocessing import Process,Pip ...
- 并发编程7 管道&事件&信号量&进程池(同步和异步方法)
1,管道 2.事件 3.信号量 4.进程池的介绍&&进程池的map方法&&进程池和多进程的对比 5.进程池的同步方法和异步方法 6.重新解释同步方法和异步方法 7.回调 ...
- python之路--管道, 事件, 信号量, 进程池
一 . 管道 (了解) from multiprocessing import Process, Pipe def f1(conn): # 管道的recv 里面不用写数字 from_main_proc ...
随机推荐
- 2017百度之星程序设计大赛 - 复赛 Arithmetic of Bomb
http://acm.hdu.edu.cn/showproblem.php?pid=6144 解法:一个简单的模拟 #include <bits/stdc++.h> using names ...
- NetCore上传多文件
.NetCore上传多文件的几种示例 本章和大家分享的是.NetCore的MVC框架上传文件的示例,主要讲的内容有:form方式提交上传,ajax上传,ajax提交+上传进度效果,Task并行处理 ...
- D. Blocks 数学题
Panda has received an assignment of painting a line of blocks. Since Panda is such an intelligent bo ...
- code review的意义
https://blog.csdn.net/brodycai/article/details/19636621
- go 从表结构生成结构体
package main import ( "fmt" "github.com/gohouse/converter" ) func main() { // 初始 ...
- Spring Boot 集成 PageHelper
配置一:在 [pom.xml] 文件中引入依赖 <!-- mybatis的分页插件 --> <dependency> <groupId>com.github.pag ...
- 192.168.28.168:3000打开网页无法调试localhost为前缀的接口
最近我在IIS上发布.net Core API的时候发现 当我用localhost去打开我的web项目时 并且,ajax调用的接口前缀为localhost时候,运行正确 但是当我用192.168.28 ...
- SQL数据库基础三
- Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [2002] No such file or directory解决方法
今天用pdo连接mysql遇到一个奇怪的问题,host设为127.0.0.1可以连接成功,设为localhost就会报如下的错误: PHP Fatal error: Uncaught excepti ...
- 对fgets末尾'\0'的处理
之所以要对fgets自动添加的字符进行处理的原因之一是:当你想比较输入的字符时,你会发现输入的字符和源码用来进行对比的字符一模一样,但是使用strcmp比较时就是不一样,原因就是fgets对输入字符添 ...