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

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

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

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

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

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. VC++ 6.0 C8051F340 USB 通信 CAN 数据解析

    // HelloWorld.cpp : Defines the entry point for the console application. // /*********************** ...

  2. 如何释放vector变量

    std::vector<cv::Point> probp; std::vector<int> plabel; plabel.clear(); std::vector<in ...

  3. 偶尔用得上的MySQL操作

    数据库编码 查看数据库编码 use xxx show variables like 'character_set_database'; 切换数据库编码 alter database xxx CHARA ...

  4. 设置tab标签页 遮挡部分

    效果如下: 主要代码: <div class="need-detail"> <div class="top-title"> <sp ...

  5. Centos7 通过SSH使用密钥实现免密登录

    Public Key认证的主要魅力在于认证时承诺不必提供密码就能够同远程系统建立连接. Public Key认证的基础在于一对密钥,public key和private key,public key对 ...

  6. spring cloud 知识点

    优秀的介绍资料: 资料 地址 spring cloud 中文网 https://springcloud.cc/ spring cloud 介绍 https://www.jianshu.com/p/74 ...

  7. shell教程-002:常见的Shell种类

    Shell是一种脚本语言,那么,就必须有解释器来执行这些脚本. Unix/Linux上常见的Shell脚本解释器有bash.sh.csh.ksh等,习惯上把它们称作一种Shell.我们常说有多少种Sh ...

  8. linux同一台机子上用多个git 账号

    Step 1 - Create a New SSH KeyWe need to generate a unique SSH key for our second GitHub account. ssh ...

  9. Nginx 整合 FastDFS 实现文件服务器

    原文地址:Nginx 整合 FastDFS 实现文件服务器 博客地址:http://www.extlight.com 一.前言 本篇衔接<FastDFS 环境搭建>内容进行讲解,上篇文章我 ...

  10. AngularJs $scope 里面的$apply 方法和$watch方法

    Angular $scope 里面的$apply 方法 Scope提供$apply方法传播Model变化 <!DOCTYPE html> <html> <head> ...