研究了下multiprocessing.managers,略有收获,随笔一篇;

核心思路是构造一个manager进程,这个进程可以通过unix socket或tcp socket与其它进程通信;因为利用了socket,所以通信的进程间不要求具备父子关系,甚至可以跨主机(通过tcp socket);

通过manager进行数据结构共享,可以应用于很多的IPC场景;这里只做一个示例,在manager内维护一个队列,做为生产者消费者模型中的消息队列;

# coding:utf-8

import os
import time
import subprocess from multiprocessing import Process
#from multiprocessing.managers import SyncManager
from multiprocessing.managers import BaseManager
from multiprocessing import JoinableQueue #父进程
pid = os.getpid()
print("parent pid %d" % pid) class TestManager(BaseManager):
pass #用于共享的队列
jqueue = JoinableQueue() #用于获取队列的方法
def _get_queue():
return jqueue #启动server(manager)
def make_server(port, authkey):
# 注册rpc,获取共享的队列(的代理,这段代码的实现很有意思,建议看看源码)
TestManager.register("get_queue",callable=lambda : _get_queue())
# 如果要走tcp socket,就用这一行
#manager = TestManager(address=('', port), authkey=authkey)
# 如果要走unix socket,就用这一行
manager = TestManager(authkey=authkey)
# 启动server(manager)进程
manager.start()
return manager # consumer进程的入口
def do_consume(manager):
print ("consumer pid %d" % os.getpid())
queue=manager.get_queue()
count = 0
while True:
item = queue.get(block=True)
#print(item)
#time.sleep(1)
queue.task_done()
if item is None:
conn = queue._tls.connection
break
count += 1
print ("done consuming %d" % count) #构造新的manager实例做为client连接manager server
def make_client(address, authkey):
# 注册rpc,用于非父子进程环境时,新构造的manager识别rpc方法
TestManager.register("get_queue")
manager = TestManager(address=address, authkey=authkey)
manager.connect()
return manager # producer进程的入口
def do_produce(address, authkey):
print ("producer pid %d" % os.getpid())
client=make_client(address, authkey)
queue=client.get_queue()
for i in range(10000):
queue.put(i, block=True)
print ("done producing") # terminator进程的入口
def do_terminate(address, authkey):
client=make_client(address, authkey)
queue=client.get_queue()
queue.put(None, block=True) authkey = b'foo'
manager=make_server(6666, authkey)
address = manager._address
# 查看manager的进程号
print ("manager pid %d" % manager._process.ident) # 通过父子进程变量传递的方式,向consumer进程传递manager
consumer = Process(target=do_consume, args=(manager, ))
consumer.start() # 伪造非父子进程传递address和authkey的方式,向producer进程传递连接manager需要的信息
producer = Process(target=do_produce, args=(address, authkey))
producer.start() # 查看当前的进程树
status, output = subprocess.getstatusoutput('pstree -p %d' % pid)
print (output) producer.join() # 伪造非父子进程传递address和authkey的方式,再启动一个terminator进程结束通信
terminator = Process(target=do_terminate, args=(address, authkey))
terminator.start()
terminator.join() consumer.join()

  

以上示例代码的过程如下:

  1. 构造manager server;
  2. 构造一个consumer进程,直接从父进程获取到manager对象;
  3. 再构造一个producer进程,通过传递address和authkey,新构造manager client,并连接manager server;
  4. producer获取到共享队列,生产消息;
  5. consumer获取到共享队列,消费消息;
  6. terminator(producer)生产一个空消息;
  7. consumer获取到空消息,消费结束;

结果:

parent pid 30460
manager pid 30461
consumer pid 30463
producer pid 30464
python(30460)-+-pstree(30465)
|-python(30461)-+-{python}(30462)
| |-{python}(30472)
| |-{python}(30474)
| `-{python}(30475)
|-python(30463)
`-python(30464)
done producing
done consuming 10000

  

可以看到共生成4个子进程,一个manager server、一个consumer、一个producer、还有一个pstree查看进程树;

利用multiprocessing.managers开发跨进程生产者消费者模型的更多相关文章

  1. python 全栈开发,Day39(进程同步控制(锁,信号量,事件),进程间通信(队列,生产者消费者模型))

    昨日内容回顾 python中启动子进程并发编程并发 :多段程序看起来是同时运行的ftp 网盘不支持并发socketserver 多进程 并发异步 两个进程 分别做不同的事情 创建新进程join :阻塞 ...

  2. python开发进程:互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型

    一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终 ...

  3. 进程,线程,GIL,Python多线程,生产者消费者模型都是什么鬼

    1. 操作系统基本知识,进程,线程 CPU是计算机的核心,承担了所有的计算任务: 操作系统是计算机的管理者,它负责任务的调度.资源的分配和管理,统领整个计算机硬件:那么操作系统是如何进行任务调度的呢? ...

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

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

  5. Python之网路编程之-互斥锁与进程间的通信(IPC)及生产者消费者模型

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

  6. python并发编程之多进程(二):互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型

    一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终 ...

  7. 进击的Python【第九章】:paramiko模块、线程与进程、各种线程锁、queue队列、生产者消费者模型

    一.paramiko模块 他是什么东西? paramiko模块是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接. 先来个实例: import param ...

  8. 多道技术 进程 线程 协程 GIL锁 同步异步 高并发的解决方案 生产者消费者模型

    本文基本内容 多道技术 进程 线程 协程 并发 多线程 多进程 线程池 进程池 GIL锁 互斥锁 网络IO 同步 异步等 实现高并发的几种方式 协程:单线程实现并发 一 多道技术 产生背景 所有程序串 ...

  9. 2.Python进程间的通信之队列(Queue)和生产者消费者模型

    一.队列 1.1 概念介绍-----multiprocess.Queue 创建共享的进程队列,Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递. Queue([maxsize] ...

随机推荐

  1. [LeetCode] Design HashMap 设计HashMap

    Design a HashMap without using any built-in hash table libraries. To be specific, your design should ...

  2. 太原面经分享:如何在vue面试环节,展示你晋级阿里P6+的技术功底?

    前言 一年一度紧张刺激的高考开始了,与此同时,我也没闲着,奔走在各大公司的前端面试环节,不断积累着经验,一路升级打怪. 最近两年,太原作为一个准二线城市,各大互联网公司的技术栈也在升级换代,假如你在太 ...

  3. javascript的数组之splice()

    splice()方法通过删除现有元素和/或添加新元素来更改一个数组的内容.修改数组自身 var months = ['Jan', 'March', 'April', 'June']; months.s ...

  4. day 25 二十五、抽象类、多态、鸭子、反射、异常处理

    一.接口思想 1.接口:建立关联的桥梁,方便管理代码 python中没有接口语法 def jiao(): pass def chi(): pass def pao(): pass # 清晰知道操作的功 ...

  5. java_基础_异常

    之前只是了解的最基础的异常形式,没有过多的深入 今天因为一些原因了解了一下 下面来说说异常的几种形式 1.try-catch语句块 代码示例 class test{ public static voi ...

  6. ES6的字符串和数值的扩展

    字符串扩展 对于处理大于两个字节(大于0xffff)的字符,let str =’\u{20bb7}abc’ ES5中的遍历  for(let i=0;i<str.length;i++){ con ...

  7. 29个人,耗时84天,硬刚Python,实验结果如下。

    真有动漫风格的编程书籍? 上图,就是日本出版的编程书籍.为什么要搞成动漫风格?因为学编程常常会枯燥,难以坚持.法国思想家布封说:所谓天才,就是坚持不懈的意思.大家学编程,转行.涨薪.加强技能,无论是何 ...

  8. 20175211 2018-2019-2 《Java程序设计》第五周学习总结

    目录 教材学习内容总结 第六章 接口与实现 教材学习中的问题和解决过程 代码调试中的问题和解决过程 代码托管 上周考试错题总结 学习进度条 参考资料 教材学习内容总结 第六章 接口与实现 6.1 接口 ...

  9. 浅析MySQL InnoDB的隔离级别

    MySQL InnoDB存储引擎中事务的隔离级别有哪些?对应隔离级别的实现机制是什么? 本文就将对上面这两个问题进行解答,分析事务的隔离级别以及相关锁机制. 隔离性简介 隔离性主要是指数据库系统提供一 ...

  10. 在eclipse中的交叉编译

    1.硬件是Arm 9的板子,运行的系统是Ubuntu 12.05 2.电脑虚拟机上安装的系统是Ubuntu 10.04,程序的开发都是在虚拟机上完成,开发IDE是eclipse 3.eclipse 默 ...