• 44_并发编程-数据共享


    一、引入
        
      展望未来,基于消息传递的并发编程是大势所趋;即便是使用线程,推荐做法也是将程序设计为大量独立的线程集合。通过消息队列交换数据。这样极大地减少了对使用锁定和其他同步手段的需求,还可以扩展到分布式系统中。
      进程间应该尽量避免通信,即便需要通信,也应该选择进程安全的工具来避免加锁带来的问题,应该尽量避免使用本节所讲的共享数据的方式,以后我们会尝试使用数据库来解决进程之间的数据共享问题。
     
    二、Manager模块 - 实现数据共享
        
      1、定义
      进程间数据是独立的,可以借助于队列或管道实现通信,二者都是基于消息传递的;虽然进程间数据独立,但可以通过Manager实现数据共享,事实上Manager的功能远不止于此。
      多进程共同去处理共享数据的时候,就和我们多进程同时去操作一个文件中的数据是一样的,不加锁就会出现错误的结果,进程不安全的,所以也需要加锁
    1 A manager object returned by Manager() controls a server process which holds Python objects and allows other processes to manipulate them using proxies.
    2 
    3 A manager returned by Manager() will support types list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Barrier, Queue, Value and Array.
    官方解释
     1 from multiprocessing import Process,Manager
     2 
     3 def func(m_dic):
     4     m_dic['name'] = 'alex_luffy'    # 子进程对数据进行了修改
     5 
     6 if __name__ == '__main__':
     7     m = Manager()
     8     m_dic = m.dict({'name':'alex'})
     9     print('主进程', m_dic)    # 先记录一下原始数据是啥样的
    10     p = Process(target=func,args=(m_dic,))    # 将字典数据传递给子进程
    11     p.start()
    12     p.join()    # 先让子进程执行完毕
    13 
    14     print('主进程',m_dic)
    15 结果:
    16 主进程 {'name': 'alex'}
    17 主进程 {'name': 'alex_luffy'}    - m_dic内的数据被子进程修改了
    View Code
     
      2、创建多进程取修改子进程的数据(会出现数据不安全->会导致数据混乱加锁解决)
     1 # 设置一个100数字,创建20个进程,分别去减一
     2 
     3 from multiprocessing import Process,Manager,Lock
     4 
     5 def func(m_dic,ml):
     6     #不加锁的情况会出现数据错乱
     7     # m_dic['count'] -= 1
     8     
     9     #加锁,这是另外一种加锁形式
    10     with ml:
    11         m_dic['count'] -= 1
    12 
    13     #等同
    14     # ml.acquire()
    15     # m_dic['count'] -= 1
    16     # ml.release()
    17 
    18 if __name__ == '__main__':
    19     m = Manager()
    20     ml = Lock()
    21     m_dic = m.dict({'count':100})
    22     # print('主进程', m_dic)
    23     p_list = []
    24 
    25     #开启20个进程来对共享数据进行修改
    26     for i in range(20):
    27         p1 = Process(target=func,args=(m_dic,ml,))
    28         p1.start()
    29         p_list.append(p1)
    30     [ppp.join() for ppp in p_list]
    31 
    32     print('主进程',m_dic)
    解决数据不安全
       
      3、总结
      下面要讲的信号量和事件也相当于锁,也是全局的,所有进程都能拿到这些锁的状态,进程之间这些锁啊信号量啊事件啊等等的通信,其实底层还是socekt,只不过是基于文件的socket通信,而不是跟上面的数据共享啊空间共享啊之类的机制,我们之前学的是基于网络的socket通信,还记得socket的两个家族吗,一个文件的一个网络的,所以将来如果说这些锁之类的报错,可能你看到的就是类似于socket的错误,简单知道一下就可以啦~~~
     
     
  • 相关阅读:
    ubuntu 安裝QQ ,WEIXIN,百度WP等
    深度学习基础--Bottleneck(瓶颈) Architectures
    sql 函数
    线性回归
    二元逻辑回归
    参数检验
    DrawFrameControl 绘制标准控件
    SetProcessWorkingSetSize 降低程序运行内存
    【转载】VC IME 通信
    【转载】EmptyWorkingSet 程序运行内存整清理
  • 原文地址:https://www.cnblogs.com/hq82/p/9851640.html
Copyright © 2020-2023  润新知