python之管道, 事件, 信号量, 进程池
管道:双向通信 2个进程之间相互通信
from multiprocessing import Process, Pipe def f1(conn):
from_zjc_msg = conn.recv()
print('我是子进程')
print('来自主进程的消息:', from_zjc_msg) if __name__ == '__main__':
conn1, conn2 = Pipe() # 创建一个管道对象, 全双工, 返回管道的两端, 但是一端发送的消息,只能另一端接受;自己这一端无法接收
# 可以将一端或两端发送给其他的进程, 那么多个进程之间就这一通过这一管道进行通信
p1 = Process(target=f1, args=(conn2, ))
p1.start()
conn1.send('有点困了') print('我是主进程')

Event用法:
from mutiprocessing import Event # 导入Event模块
event=Event() #设置一个事件对象, 初始标志位是False
event.set() # 将标志位改为True
event.clear() # 将标志位改为False
event.wait() # 等待设置标志位, 直到为True,再 继续向下执行
from multiprocessing import Process, Event e = Event() # 创建事件对象, 这个对象的初始状态为False
print('e的状态是', e.is_set()) print('程序运行到了这里') e.set() # 将e的状态改为True
print('e的状态是', e.is_set())
# e.clear() # 将e的状态改为False e.wait() # e这个事件对象如果值为False, 就在此处等待.
print('程序过了wait')

基于事件的进程通信
import time
from multiprocessing import Process, Event def f1(e):
time.sleep(2)
n = 100
print('子进程计算结果为:', n)
e.set() if __name__ == '__main__':
e = Event()
p = Process(target=f1, args=(e, ))
p.start() print('主进程等待.....')
e.wait()
print('结果已经出来, 可以拿到该值')

信号量(Semaphore),用于控制线程并发数
需要导入模块:
from multiprocessing import Process, Semaphore
重要方法有2个 对象.acquire() 和 对象.release()
import time
import random
from multiprocessing import Process, Semaphore def f1(i, s):
s.acquire() print('%s号嘉宾进去了' % i)
time.sleep(random.randint(1, 3))
print('%s号嘉宾出来了' % i)
s.release() if __name__ == '__main__':
s = Semaphore(2) # 计数器2, acquire 一次减一, 为0, 其他人等待, release加1
for i in range(5):
p = Process(target=f1, args=(i, s))
p.start()

进程池:定义一个池子,在里面放上固定数量的进程,有需求来了,就拿一个池中的进程来处理任务,等到处理完毕,进程并不关闭,而是将进程再放回进程池中继续等待任务。
如果有很多任务需要执行,池中的进程数量不够,任务就要等待之前的进程执行任务完毕归来,拿到空闲进程才能继续执行。也就是说,池中进程的数量是固定的,
那么同一时间最多有固定数量的进程在运行。
# # 进程池和多进程执行时间的对比
import time
from multiprocessing import Process, Pool def f(n):
for i in range(5):
n += i
if __name__ == '__main__':
# 统计进程池执行100个任务的时间
s_time = time.time()
pool = Pool(4) # 里面这个参数是指定进程池中有多少个进程, 4表示4个进程, 如果不传参, 默认开启的进程数一般是cpu的个数
pool.map(f, range(100)) # 参数数据必须是可迭代的, 异步提交任务, 自带join功能
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=f, 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)

进程池同步方法:
import time
from multiprocessing import Process, Pool def f1(n):
# print(n)
time.sleep(2)
return n * 2 if __name__ == '__main__':
pool = Pool(2) for i in range(5):
print('xxxxx')
res = pool.apply(f1, args=(i, ))
print(res)

结果: 先执行xxxxx 过2s执行0, xxxxx 过2s执行2 xxxxx
进程池异步:
import time
from multiprocessing import Process, Pool def f1(n):
time.sleep(2)
return n * 2 if __name__ == '__main__':
pool = Pool(2)
res_list = [ ]
for i in range(5):
print('xxxxx')
res = pool.apply_async(f1, args=(i,))
res_list.append(res)
for i in res_list:
print(i.get())

进程池的回调函数:
import os
from multiprocessing import Pool, Process def f1(n):
print('进程池里面的进程pid', os.getpid())
print(n)
return 2 * n def f2(n):
print('回调函数里面的进程pid', os.getpid())
print(n) if __name__ == '__main__':
pool = Pool(4)
res = pool.apply_async(f1, args=(5,), callback=f2)
pool.close()
pool.join()
print('主程序里面的进程pid', os.getpid())

python之管道, 事件, 信号量, 进程池的更多相关文章
- python之路--管道, 事件, 信号量, 进程池
一 . 管道 (了解) from multiprocessing import Process, Pipe def f1(conn): # 管道的recv 里面不用写数字 from_main_proc ...
- Python 并发编程(管道,事件,信号量,进程池)
管道 Conn1,conn2 = Pipe() Conn1.recv() Conn1.send() 数据接收一次就没有了 from multiprocessing import Process,Pip ...
- python并发编程之进程2(管道,事件,信号量,进程池)
管道 Conn1,conn2 = Pipe() Conn1.recv() Conn1.send() 数据接收一次就没有了 from multiprocessing import Process,Pip ...
- day 32 管道 事件 信号量 进程池
一.管道(多个时数据不安全) Pipe 类 (像队列一样,数据只能取走一次) conn1,conn2 = Pipe() 建立管道 .send() 发送 .recv() 接收 二.事 ...
- 并发编程7 管道&事件&信号量&进程池(同步和异步方法)
1,管道 2.事件 3.信号量 4.进程池的介绍&&进程池的map方法&&进程池和多进程的对比 5.进程池的同步方法和异步方法 6.重新解释同步方法和异步方法 7.回调 ...
- python--管道, 事件, 信号量, 进程池
一 . 管道 (了解) from multiprocessing import Process, Pipe def f1(conn): # 管道的recv 里面不用写数字 from_main_proc ...
- Python多进程库multiprocessing中进程池Pool类的使用[转]
from:http://blog.csdn.net/jinping_shi/article/details/52433867 Python多进程库multiprocessing中进程池Pool类的使用 ...
- python 管道 事件(Event) 信号量 进程池(map/同步/异步)回调函数
####################总结######################## 管道:是进程间通信的第二种方式,但是不推荐使用,因为管道会导致数据不安全的情况出现 事件:当我运行主进程的 ...
- day 32 管道,信号量,进程池,线程的创建
1.管道(了解) Pipe(): 在进程之间建立一条通道,并返回元组(conn1,conn2),其中conn1,conn2表示管道两端的连接对象,强调一点:必须在产生Process对象之前产生管道. ...
随机推荐
- 记web模拟手机环境已经微信开发者工具中可正常运行,实体机运行报错问题
问题描述: 有个手机微信OA的项目 用户信息采用cookie方式保存.发布后使用chorme浏览器进行模拟访问测试发现一切运行顺畅,使用微信开发者工具进行测试也一切正常. 采用实体机进行测试时,用微信 ...
- Linux pwn入门教程(3)——ROP技术
作者:Tangerine@SAINTSEC 原文来自:https://bbs.ichunqiu.com/thread-42530-1-1.html 0×00 背景 在上一篇教程的<shellco ...
- JS应用实例5:全选、动态添加
HTML代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <t ...
- .NET手记-ASP.NET MVC快速分页的实现
对于Web应用,展示List是很常见的需求,随之而来的常见的分页组件.jQuery有现成的分页组件,网上也有着大量的第三方分页组件,都能够快速实现分页功能.但是今天我描述的是用基本的C#和html代码 ...
- javascript 最全面的数组操作合集
一.数组添加.删除.替换.截取操作 1.arr.unshift(1) 在数组头部添加一个元素 1 (直接改变原数组,返回值为添加元素后数组的length) 2.arr.shift() 在数组的头部删除 ...
- Python基础教程(第3版) 笔记(二)
1.8模块Python提供了完成(某人的年 龄为32.9,并想将这个值向下圆整为32,因为他还没有满33岁)这种任务的函 数floor.导入模块,可以使用特殊命令import.函数floor包含在模块 ...
- 使用Chrome开发者工具调试Android端内网页(微信,QQ,UC,App内嵌页等)
使用Chrome开发者工具调试Android端内网页(微信,QQ,UC,App内嵌页等) 前言 移动端页面调试一直是好多朋友头疼的问题,iOS 由于其封闭的特性和整体较高的性能,整体适配相对好做,调试 ...
- MongoDB索引管理-索引的创建、查看、删除
索引是提高查询查询效率最有效的手段.索引是一种特殊的数据结构,索引以易于遍历的形式存储了数据的部分内容(如:一个特定的字段或一组字段值),索引会按一定规则对存储值进行排序,而且索引的存储位置在内存中, ...
- [P4921] 情侣?给我烧了!
回顾一下错排公式 错排问题: 设n位错排数为D[n].考虑元素1的位置,设置为k(有n-1中 ):在考虑元素k的位置, 若为1,则转换为n-2位的错排:否则,视元素k为元素1(不能放在位置1),转换为 ...
- shell编程中的if语句
if语句在任何编程中都是必不可少.至关重要的分支语句,shell也是如此,只不过各种编程中的方式和格式有点不太一样 shell编程中的if语句基本格式如下: if [ X$1 = XA ];then ...