一、进程间通信

进程之间的数据是相互隔离的,例如

from multiprocessing import Process

def task():
global n # 声明全局变量
n = 999
print('子', n) if __name__ == '__main__':
p = Process(target=task )
n=10
p.start()
print('主',n) '''输出结果
主 10
子 999''' # 子进程中的数据并不会影响到父进程的数据

而想做到进程与进程之间的通信,就需要借助到第三方的媒介进行数据的交换获取等操作。

IPC(Inter-Process Communication)进程间通讯

二、队列

multiprocess.Queue

创建共享的进程队列,Queue是多进程安全队列,可以使用Queue实现多进程之间的数据传递。

Queue([maxsize]) #创建共享的进程队列
# maxsize是队列中允许的最大项数。如果省略此参数,则无大小限制

底层队列使用管道和锁定实现。

Queue方法

Queue([maxsize]):创建共享的进程队列。

Queue实例化之后q具有以下方法:

q.get([ block [ ,timeout ] ])
'''返回q中的一个项目。如果q为空,此方法将阻塞,直到队列中有项目可用为止。
block用于控制阻塞行为,默认为True. 如果设置为False,
将引发Queue.Empty异常(定义在Queue模块中)。
timeout是可选超时时间,用在阻塞模式中。
如果在制定的时间间隔内没有项目变为可用,将引发Queue.Empty异常。'''
from multiprocessing import Queue if __name__ == '__main__': q = Queue(3) q.put('001')
q.put('002')
q.put('003')
print(q.get())
print(q.get())
print(q.get())
print(q.get(block=False)) # 将block设置为False就不会处在阻塞状态,一旦取不到值就会报异常。或者将timeout设定超时时间,超过这个时间取不到值也会报异常,不等待。
q.get_nowait()  # 取值不会处在阻塞状态,一旦取不到值就会报异常
q.put_nowait() # 将值放入队列。如果队列已满,就会报异常
q.put(item [, block [,timeout ] ] )
'''将item放入队列。如果队列已满,此方法将阻塞至有空间可用为止。
block控制阻塞行为,默认为True。如果设置为False,将引发Queue.Empty异常(定义在Queue库模块中)。
timeout指定在阻塞模式中等待可用空间的时间长短。超时后将引发Queue.Full异常。'''
q.qsize()
'''返回队列中目前项目的正确数量。此函数的结果并不可靠,
因为在返回结果和在稍后程序中使用结果之间,队列中可能添加或删除了项目。
在某些系统上,此方法可能引发NotImplementedError异常。'''
q.empty()
'''判断q队列是否为空,空返回True,否则返回False。
如果其他进程或线程正在往队列中添加项目,结果是不可靠的。也就是说,
在返回和使用结果之间,队列中可能已经加入新的项目。'''
q.full() '''如果q已满,返回为True. 由于线程的存在,结果也可能是不可靠的(参考q.empty()方法)。'''

Queue解决进程间数据隔离问题

from multiprocessing import Queue, Process
import time def task(q):
q.put(time.strftime('%Y-%m-%d %H:%M:%S'))
print('数据放完了') if __name__ == '__main__':
q = Queue(3)
p = Process(target=task, args=(q,))
p.start()
res = q.get()
print('取到了%s' % res)
print('主') '''输出结果
数据放完了
取到了2021-07-21 15:46:57
主'''

批量生产数据放入队列再批量获取结果

from multiprocessing import Queue, Process
import time def q_put(q):
q.put(time.strftime('%Y-%m-%d %H:%M:%S'))
print('数据放完了') def q_get(q):
print(q.get()) if __name__ == '__main__':
q = Queue(3)
p1 = Process(target=q_put, args=(q,))
p2 = Process(target=q_put, args=(q,))
p3 = Process(target=q_get, args=(q,))
p4 = Process(target=q_get, args=(q,))
p1.start()
p2.start()
p3.start()
p4.start()

生产者消费者模型

import os
import random
import time
from multiprocessing import Process, Queue,set_start_method # 针对mac用Queue出bug状况 def producer(queue, product):
for i in range(1, 11):
print('%s号流水线生产了第%s个%s' % (i, i, product))
time.sleep(random.random())
queue.put('第%s个%s' % (i, product)) def consumer(queue):
while True:
res = queue.get()
if not res: break # 发现none直接结束运行
print('%s消费者取走了%s' % (os.getpid(), res)) if __name__ == '__main__':
set_start_method('fork') # 针对mac用Queue出bug状况
q = Queue(3)
producer_p = Process(target=producer, args=(q, '大可乐'))
consumer_p = Process(target=consumer, args=(q,))
producer_p.start()
consumer_p.start()
producer_p.join() # 让子进程先运行完再添加标志
q.put(None)
多生产者 多消费者
# 生产者:
def producer(queue, food):
# 把数据全部放在Queue
for i in range(10):
data = "这个进程id:%s, 生产了%s个%s" % (os.getpid(), i, food)
print(data) time.sleep(random.randint(1, 3))
# 放入数据
queue.put("第%s个%s" % (i, food)) def consumer(queue):
while True:
res = queue.get()
if not res:break
data = "这个进程id:%s, 吃了%s" % (os.getpid(), res)
print(data) if __name__ == '__main__':
q = Queue(3)
p1 = Process(target=producer, args=(q, '面包'))
p2 = Process(target=producer, args=(q, '奶粉'))
p3 = Process(target=producer, args=(q, '冰淇淋'))
p1.start()
p2.start()
p3.start() p4 = Process(target=consumer, args=(q,))
p5 = Process(target=consumer, args=(q,))
p4.start()
p5.start() # time.sleep(1000)
# none放在这里是不行的,原因是主进程直接执行了put none, 消费者直接获取到None, 程序直接结束了
# p.join()
# q.put(None) p1.join()
p2.join()
p3.join() q.put(None)
q.put(None)
q.put(None)
多生产者 多消费者  消费者大于生产者
# 生产者:
def producer(queue, food):
# 把数据全部放在Queue
for i in range(10):
data = "这个进程id:%s, 生产了%s个%s" % (os.getpid(), i, food)
print(data) time.sleep(random.randint(1, 3))
# 放入数据
queue.put("第%s个%s" % (i, food)) def consumer(queue, name):
while True:
try: res = queue.get(timeout=5)
if not res:break
data = "这个消费者:%s, 吃了%s" % (name, res)
print(data)
except Exception as e:
print(e)
break if __name__ == '__main__':
q = Queue(3)
p1 = Process(target=producer, args=(q, '面包'))
p2 = Process(target=producer, args=(q, '奶粉'))
p3 = Process(target=producer, args=(q, '冰淇淋'))
p1.start()
p2.start()
p3.start() p4 = Process(target=consumer, args=(q, '许鹏'))
p5 = Process(target=consumer, args=(q, '勇哥'))
p6 = Process(target=consumer, args=(q, '勇哥2'))
p7 = Process(target=consumer, args=(q, '勇哥3'))
p4.start()
p5.start()
p6.start()
p7.start() # time.sleep(1000)
# none放在这里是不行的,原因是主进程直接执行了put none, 消费者直接获取到None, 程序直接结束了
# p.join()
# q.put(None) p1.join()
p2.join()
p3.join() q.put(None)
q.put(None)
q.put(None)

进程之间的通信(multiprocess.Queue)的更多相关文章

  1. c# IPC实现本机进程之间的通信

    IPC可以实现本地进程之间通信.这种用法不是太常见,常见的替代方案是使用wcf,remoting,web service,socket(tcp/pipe/...)等其他分布式部署方案来替代进程之间的通 ...

  2. python全栈开发 * 进程之间的通信,进程之间数据共享 * 180726

    进程之间的通信(IPC)队列和管道一.队列 基于管道实现 管道 + 锁 数据安全(一).队列 队列遵循先进先出原则(FIFO) 多用于维护秩序,买票,秒杀 队列的所有方法: put()(给队列里添加数 ...

  3. day34——僵尸进程和孤儿进程、互斥锁、进程之间的通信

    day34 僵尸进程和孤儿进程 基于unix环境(linux,macOS) 主进程需要等待子进程结束之后,主进程才结束 主进程时刻监测子进程的运行状态,当子进程结束之后,一段时间之内,将子进程进行回收 ...

  4. Python并发编程03 /僵孤进程,孤儿进程、进程互斥锁,进程队列、进程之间的通信

    Python并发编程03 /僵孤进程,孤儿进程.进程互斥锁,进程队列.进程之间的通信 目录 Python并发编程03 /僵孤进程,孤儿进程.进程互斥锁,进程队列.进程之间的通信 1. 僵尸进程/孤儿进 ...

  5. python进程之间的通信——Queue

    我们知道进程之间的数据是互不影响的,但有时我们需要在进程之间通信,那怎么办呢? 认识Queue 可以使用multiprocessing模块的Queue实现多进程之间的数据传递,Queue本身是一个消息 ...

  6. 《Python》进程之间的通信(IPC)、进程之间的数据共享、进程池

    一.进程间通信---队列和管道(multiprocess.Queue.multiprocess.Pipe) 进程间通信:IPC(inter-Process Communication) 1.队列 概念 ...

  7. python网络编程中互斥锁与进程之间的通信

    一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...

  8. ython实现进程间的通信有Queue,Pipe,Value+Array等,其中Queue实现多个进程间的通信,而Pipe实现两个进程间通信,而Value+Array使用得是共享内存映射文件的方式,所以速度比较快

    1.Queue的使用 from multiprocessing import Queue,Process import os,time,random #添加数据函数 def proc_write(qu ...

  9. UNIX标准C - 进程之间的通信

    一.基本概念 进程间通信IPC:进程之间交换数据的过程叫进程间通信 进程间同性的方式: 简单的进程间的通信: 命令行:父进程通过exec函数创建子进程是可以附加一些数据 环境变量表:父进程通过exec ...

随机推荐

  1. WUSTCTF2020 funnyre

    运行起来,发现啥都没反应也没输出,ida直接打开,反编译 .init函数动调了下,发现没啥用,主要核心在于main函数,直接跟进去 发现了核心逻辑,有花指令,直接去掉,发现还挺多,然后似乎不影响观看, ...

  2. buu [V&N2020 公开赛]strangeCpp

    拖入ida,静态调试一下,本来想动调的,发现一直缺dll.没办法,只能头铁,静态 找到主函数,然后并没有发现什么,找了半天,没结果,后面也是看了大佬wp,才找到解决方式,感觉这种只能通过动调来找到关键 ...

  3. 深度解析HashMap底层实现架构

    摘要:分析Map接口的详细使用以及HashMap的底层是如何实现的? 本文分享自华为云社区<[图文并茂]深度解析HashMap高频面试及底层实现结构![奔跑吧!JAVA]>,原文作者:灰小 ...

  4. Vue中watch与computed的区别

    一. 计算属性(computed) 1.计算属性是为了模板中的表达式简洁,易维护,符合用于简单运算的设计初衷.对于运算过于复杂,冗长,且不好维护,因此我们对于复杂的运算应该 使用计算属性的方式去书写. ...

  5. 「AGC010F」 Tree Game

    「AGC010F」 Tree Game 传送门 切了一个 AGC 的题,很有精神. 于是决定纪念一下. 首先如果任意一个人在点 \(u\),他肯定不会向点权大于等于 \(a_u\) 的点走的,因为此时 ...

  6. SOA-面向服务的架构

    一.什么是SOA? SOA 面向服务架构,是一个架构思想,是跨语言和平台的.SOA宗旨简单明了,根据项目服务完成架构搭建,以服务为基准点完成组件化和模块化.提供服务是项目的基本内容,其他的contro ...

  7. SVN教程(包括小乌龟) 全图解

    转载自http://www.cnblogs.com/armyfai/p/3985660.html SVN使用教程总结 SVN简介: 为什么要使用SVN? 程序员在编写程序的过程中,每个程序员都会生成很 ...

  8. 高性能内存图数据库RedisGraph(二)

    这篇文章主要介绍用一下RedisGraph的历史和现状. 2018年5月,Redis Labs发布了RedisGraph的预览/测试版.6个月后,在Redis Labs和开源社区的开发者们的共同努力下 ...

  9. 扩展欧几里得(exgcd)-求解不定方程/求逆元

    贝祖定理:即如果a.b是整数,那么一定存在整数x.y使得ax+by=gcd(a,b).换句话说,如果ax+by=m有解,那么m一定是gcd(a,b)的若干倍.(可以来判断一个这样的式子有没有解)有一个 ...

  10. Navicat Premium 12安装及破解

    特别提醒,Navicat Premium 12安装包请用我给的链接下载,不然会无法破解 下载Navicat Premium 12地址:https://pan.baidu.com/s/1AQsryKpJ ...