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

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

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

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

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

Manager 介绍

  1. 进程间数据是独立的,可以借助于队列或管道实现通信,二者都是基于消息传递的
  2. 虽然进程间数据独立,但可以通过Manager实现数据共享,事实上Manager的功能远不止于此
  3.  
  4. A manager object returned by Manager() controls a server process which holds Python objects and allows other processes to manipulate them using proxies.
  5.  
  6. 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,实现通信。

简单使用

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

再看循环修改的例子

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

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

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

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

还有另外一种写法

  1. from multiprocessing import Manager,Process,Lock
  2. def func(dic,lock):
  3. with lock: # 上下文管理 :必须有一个开始动作 和 一个结束动作的时候
  4. dic['count'] = dic['count'] -1 # 每次减1
  5.  
  6. if __name__ == '__main__':
  7. m = Manager() # 创建一个server进程
  8. lock = Lock() #创建锁
  9. dic = m.dict({'count':100}) #这是一个特殊的字典
  10. p_lst = [] # 定义一个空列表
  11. for i in range(100): # 启动100个进程
  12. p = Process(target=func,args=[dic,lock])
  13. p_lst.append(p) # 进程追加到列表中
  14. p.start() # 启动进程
  15. for p in p_lst:p.join() # 等待100个进程全部结束
  16. 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. CAN中如何计算波特率并配置波特率

    //设置波特率 CAN_InitStructure.CAN_SJW=tsjw; //同步宽度 CAN_InitStructure.CAN_BS1=tbs1; //时间段1 CAN_InitStruct ...

  2. 浅谈 React

    机缘巧合认识React,翻了2天的资料,又整理了1天,也算是简单入门了;之前也学过angular,相比来说,的确React代码逻辑更加简单明了,理解起来也相对容易. React 具备以下特性:1.声明 ...

  3. POJ 2585:Window Pains(拓扑排序)

    Window Pains Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2524   Accepted: 1284 Desc ...

  4. hdu5228

    bc41第一题 德州扑克的背景,给出五张牌,问最少要换多少张牌能凑齐同花顺 其实很水,数据量很小,随便暴力,越粗暴越好,然后我wa了一发因为没有看全题目,10\11\12\13\1也是一组同花顺``` ...

  5. 使用Spring Boot操作Hive JDBC时,启动时报出错误:NoSuchMethodError: org.eclipse.jetty.servlet.ServletMapping.setDef

    使用Spring Boot操作Hive JDBC时,启动时报出错误:NoSuchMethodError: org.eclipse.jetty.servlet.ServletMapping.setDef ...

  6. stardog graphql 简单操作

    预备环境: 下载stardog 软件包 graphql 查询地址 创建一个简单数据库 ./stardog-admin db create -nstarwars graphql 查询方式 http 地址 ...

  7. sql server 创建内联表值函数

    表值函数就是返回table 的函数使用它可以方便的进行查询的处理 创建的代码如下: create FUNCTION returunclassfirstlist(  -- Add the paramet ...

  8. http-equiv 了解

    META标签是HTML语言HEAD区的一个辅助性标签,它位于HTML文档头部的<HEAD>标记和<TITLE>标记之间,它提供用户不可见的信息.meta标签通常用来为搜索引擎r ...

  9. 浅谈c++中map插入数据的用法

    map:数据的插入 在构造map容器后,我们就可以往里面插入数据了.这里讲三种插入数据的方法:第一种:用insert函数插入pair数据 map<int, string> mapStude ...

  10. package.json 文件中的版本号

    版本号,格式:"主要版本,次要版本,补丁版本" 指定版本:比如1.2.2,遵循"主版本,次要版本,补丁版本"的格式规定,安装时只安装指定版本. 波浪号(tild ...