展望未来,基于消息传递的并发编程是大势所趋

即便是使用线程,推荐做法也是将程序设计为大量独立的线程集合,通过消息队列交换数据。

这样极大地减少了对使用锁定和其他同步手段的需求,还可以扩展到分布式系统中。

但进程间应该尽量避免通信,即便需要通信,也应该选择进程安全的工具来避免加锁带来的问题。

以后我们会尝试使用数据库来解决现在进程之间的数据共享问题。

Manager 介绍

进程间数据是独立的,可以借助于队列或管道实现通信,二者都是基于消息传递的
虽然进程间数据独立,但可以通过Manager实现数据共享,事实上Manager的功能远不止于此 A manager object returned by Manager() controls a server process which holds Python objects and allows other processes to manipulate them using proxies. A manager returned by Manager() will support types list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value and Array.

Manager是一种较为高级的多进程通信方式,它能支持Python支持的的任何数据结构。
它的原理是:先启动一个ManagerServer进程,这个进程是阻塞的,它监听一个socket,然后其他进程(ManagerClient)通过socket来连接到ManagerServer,实现通信。

简单使用

from multiprocessing import Manager,Process
def func(dic):
dic['count'] = dic['count'] -1
print(dic) if __name__ == '__main__':
m = Manager() # 创建一个server进程
dic = m.dict({'count':100}) #这是一个特殊的字典
p = Process(target=func,args=[dic,])
p.start()
p.join()

再看循环修改的例子

from multiprocessing import Manager,Process
def func(dic):
dic['count'] = dic['count'] -1 # 每次减1 if __name__ == '__main__':
m = Manager() # 创建一个server进程
dic = m.dict({'count':100}) #这是一个特殊的字典
p_lst = [] # 定义一个空列表
for i in range(100): # 启动100个进程
p = Process(target=func,args=[dic,])
p_lst.append(p) # 进程追加到列表中
p.start() # 启动进程
for p in p_lst:p.join() # 等待100个进程全部结束
print(dic) # 打印dic的值

多执行几次就会发现,dic的值再 0 1 3之间变化,同一个时间内有多个进程操作dic,就会发生数据错乱

所以需要加锁,结果就固定为{'count': 0}

from multiprocessing import Manager, Process, Lock

def func(dic, lock):
lock.acquire() # 取得锁
dic['count'] = dic['count'] - 1 # 每次减1
lock.release() # 释放锁 if __name__ == '__main__':
m = Manager() # 创建一个server进程
lock = Lock() # 创建锁
dic = m.dict({'count': 100}) # 这是一个特殊的字典
p_lst = [] # 定义一个空列表
for i in range(100): # 启动100个进程
p = Process(target=func, args=[dic, lock])
p_lst.append(p) # 进程追加到列表中
p.start() # 启动进程
for p in p_lst: p.join() # 等待100个进程全部结束
print(dic) # 打印dic的值

还有另外一种写法

from multiprocessing import Manager,Process,Lock
def func(dic,lock):
with lock: # 上下文管理 :必须有一个开始动作 和 一个结束动作的时候
dic['count'] = dic['count'] -1 # 每次减1 if __name__ == '__main__':
m = Manager() # 创建一个server进程
lock = Lock() #创建锁
dic = m.dict({'count':100}) #这是一个特殊的字典
p_lst = [] # 定义一个空列表
for i in range(100): # 启动100个进程
p = Process(target=func,args=[dic,lock])
p_lst.append(p) # 进程追加到列表中
p.start() # 启动进程
for p in p_lst:p.join() # 等待100个进程全部结束
print(dic) # 打印dic的值

使用:同一台机器上:使用 Queue

   不同机器上,使用消息中间件

进程之间的数据共享 -----Manager模块的更多相关文章

  1. manager 实现进程之间的数据共享 list dict

    manager 能够实现进程之间的数据共享 (list,dict) 如果多个进程同事修改同一份共享数据,这个时候需要加锁,保证数据的准确性. (1) dict list 可以实现进程之间的数据共享 ( ...

  2. python 全栈开发,Day40(进程间通信(队列和管道),进程间的数据共享Manager,进程池Pool)

    昨日内容回顾 进程 multiprocess Process —— 进程 在python中创建一个进程的模块 start daemon 守护进程 join 等待子进程执行结束 锁 Lock acqui ...

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

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

  4. python全栈开发,Day40(进程间通信(队列和管道),进程间的数据共享Manager,进程池Pool)

    昨日内容回顾 进程 multiprocess Process —— 进程 在python中创建一个进程的模块 start daemon 守护进程 join 等待子进程执行结束 锁 Lock acqui ...

  5. 探讨下在Delphi里面进程之间的数据共享

    进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动.它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元.现在小编就和大家来探讨一下在Delphi ...

  6. 【Linux 进程】之关于父子进程之间的数据共享分析

    之前我们通过fork()函数,得知了父子进程之间的存在着代码的拷贝,且父子进程都相互独立执行,那么父子进程是否共享同一段数据,即是否存在着数据共享.接下来我们就来分析分析父子进程是否存在着数据共享. ...

  7. python进程之间修改数据[Manager]与进程池[Pool]

    #前面的队列Queue和管道Pipe都是仅仅能再进程之间传递数据,但是不能修改数据,今天我们学习的东西就可以在进程之间同时修改一份数据 #Mnager就可以实现 import multiprocess ...

  8. python 进程之间的数据共享

    from multiprocessing import Process,Manager import os def f(d,n): d[os.getpid()] = os.getppid()#对字典d ...

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

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

随机推荐

  1. Texas Instruments matrix-gui-2.0 hacking -- app_description.php

    <?php /* * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * * * Redistrib ...

  2. poj-1239(递推关系)好难

    #include <iostream> #include <algorithm> #include <cstring> #include <cstdio> ...

  3. (4)logging(日志模块)

    日志分成几个常用的级别 debug 10 代表程序调试过程中的信息 info 20 代表普通日志信息,用户的访问等等 warning 30 警告日志,有可能出错,但是目前还没出错的 error 40 ...

  4. System.out.println()详解 和 HttpServletRequest 和 XMLHttpRequest

    System是一个类,位于java.lang这个包里面.out是这个System类的一个PrintStream类型静态属性.println()是这个静态属性out所属类PrintStream的方法. ...

  5. Centos安装git2.2.1

    由于Centos6.5使用yum -y install git 安装的git版本是 git --versiongit version 1.7.1 想要升级到2.2.1: ># yum remov ...

  6. azkaban:java任务调度系统

    github:https://github.com/azkaban/azkaban 官方网站:https://azkaban.github.io/ 好的介绍文章:http://srcct.com/20 ...

  7. 【数据库】mysql的安装

    打开下载的mysql安装文件mysql-5.0.27-win32.zip,双击解压缩,运行“setup.exe”,出现如下界面 mysql安装向导启动,按“Next”继续 选择安装类型,有“Typic ...

  8. 如何在eclipse中安装angularjs插件

    1,首先,在eclipse中使用angularjs的时候,由于没有相应的提示,导致在开发的时候给我们带来了很多的不便,需要在这上面耗费一些时间.那么这时候我们都在想可不可以让eclipse也和一些前端 ...

  9. php curl模拟登录(半转载)

    参考:http://our2848884.blog.163.com/blog/static/146854834201282039334/   php curl模拟登录 参考:http://blog.c ...

  10. wxWidgets:消息处理流程

    首先解释下EventHandler. wxWidgets中EventHandler并不是简单的指消息(事件)处理函数,而是一个用于处理窗口系统消息的类.收到消息后,wxEventHandler会调用e ...