研究了下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. 阿里云 ACP 考试学习过程分享

    目录 考证意义 学习方法 ACP 报名 学习安排[重要] 考试当天 其他 经验贴 考证意义 证多不压身,证比项目经历更具有说服力,证是行业的标准认证.更多时候,是有证的人说,"证其实不重要& ...

  2. vue菜鸟从业记:完成项目最后一公里之真机测试和打包上线

    最近我朋友王小闰他们公司的项目开发已经进入收尾阶段,前后端并行开发的差不多了,联调也调过了,上篇文章里也讲到了,所谓联调,就仿佛在说“我也不知道我的接口文档写的对不对,我们验证一下吧?我也不知道我的数 ...

  3. 关于 vuex 的使用忠告

    第一.看明白这张图在说话 简单解释一下,actions接收到components的行为后actions请求api 等获取数据,提交到mutations,然后mutations中才改变state ,反映 ...

  4. Javascript获取服务器时间

    //获取服务器时间 var getServerDate = function () {     var xmlHttpRequest = null,     serverDate = new Date ...

  5. docker上部署rabbitmq

    1.docker search rabbitmq 2.docker pull rabbitmq:3.6 3.docker run -d -p 5672:5672 -p 15672:15672 --na ...

  6. [dev][go] 入门Golang都需要了解什么

    一 什么是Golang 首先要了解Golang是什么. Golang是一门计算机编程语言:可以编译成机器码的像python一样支持各种特性的高级语言. 由Google发明,发明人之一是K,就是C语言的 ...

  7. Android的几种Manager

    电话管理器TelephoneManager 第一个实例是获取网络和SIM卡信息:界面是一个列表,这里省略,Java代码如下: public class MainActivity extends Act ...

  8. flutter 学习零碎知识点01

    1.Expanded组件 占满可用空间 -----可以到达类似flex布局中  第一列占用大量空间,所以它必须包装在Expanded widget中. 写死的高度改成Expanded自动撑满屏幕如果还 ...

  9. Android数据库无缝升级方案

    软件迭代过程中,业务不断更新,也要求软件持续更新.相应地,数据库更新升级也是不可避免的一个环节.Android作为客户端应用,数据库升级相对于服务端来说会麻烦一些.常见的升级方式有: 1.删除旧表和数 ...

  10. webservice学习教程(一):理论

    一. WebService到底是什么? webservice是一种跨平台,跨语言的规范,用于不同平台,不同语言开发的应用之间的交互 WebService是一个SOA(面向服务的编程)的架构,它是不依赖 ...