python中进程间数据通讯模块multiprocessing.Manager的介绍


当前第2页 返回上一页

为了了解这个现象背后的原因, 我简单去读了一下源码, 主要有以下几段代码很关键.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

def Manager():

    '''

    Returns a manager associated with a running server process

 

    The managers methods such as `Lock()`, `Condition()` and `Queue()`

    can be used to create shared objects.

    '''

    from multiprocessing.managers import SyncManager

    m = SyncManager()

    m.start()

    return m

     

...

    def start(self, initializer=None, initargs=()):

        '''

        Spawn a server process for this manager object

        '''

        assert self._state.value == State.INITIAL

 

        if initializer is not None and not hasattr(initializer, '__call__'):

            raise TypeError('initializer must be a callable')

 

        # pipe over which we will retrieve address of server

        reader, writer = connection.Pipe(duplex=False)

 

        # spawn process which runs a server

        self._process = Process(

            target=type(self)._run_server,

            args=(self._registry, self._address, self._authkey,

                  self._serializer, writer, initializer, initargs),

            )

        ident = ':'.join(str(i) for i in self._process._identity)

        self._process.name = type(self).__name__  + '-' + ident

        self._process.start()

...

上面代码可以看出, 当我们声明了一个Manager对象的时候, 程序实际在其他进程启动了一个server服务, 这个server是阻塞的, 以此来实现进程间数据安全.
我的理解就是不同进程之间操作都是互斥的, 一个进程向server请求到这部分数据, 再把这部分数据修改, 返回给server, 之后server再去处理其他进程的请求.

回到上面的奇怪现象上, 这个操作test_dict['test'][idx] = idx实际上在拉取到server上的数据后进行了修改, 但并没有返回给server, 所以temp_dict的数据根本没有变化. 在第二段正常代码, 就相当于先向服务器请求数据, 再向服务器传送修改后的数据. 这样就可以解释这个现象了.

进程间数据安全

这个时候如果出现一种情况, 两个进程同时请求了一份相同的数据, 分别进行修改, 再提交到server上会怎么样呢? 那当然是数据产生异常. 基于此, 我们需要Manager的另一个对象, Lock(). 这个对象也不难理解, Manager本身就是一个server, dict跟lock都来自于这个server, 所以当你lock住的时候, 其他进程是不能取到数据, 自然也不会出现上面那种异常情况.

代码示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

import multiprocessing

# 1. 创建一个Manger对象

manager = multiprocessing.Manager()

# 2. 创建一个dict

temp_dict = manager.dict()

lock = manager.Lock()

temp_dict['test'] = {}

# 3. 创建一个测试程序

def test(idx, test_dict, lock):

    lock.acquire()

    row = test_dict['test']

    row[idx] = idx

    test_dict['test'] = row

    lock.release()

# 4. 创建进程池进行测试

pool = multiprocessing.Pool(4)

for i in range(100):

    pool.apply_async(test, args=(i, temp_dict, lock))

pool.close()

pool.join()

print(temp_dict)

切忌不要进程里自己新建lock对象, 要使用统一的lock对象.

本篇文章到这里就已经全部结束了,更多其他精彩内容可以关注PHP中文网的python视频教程栏目!

以上就是python中进程间数据通讯模块multiprocessing.Manager的介绍的详细内容,更多文章请关注木庄网络博客!!

返回前面的内容

相关阅读 >>

turtle.done()的作用是什么

Python关于tkinter模块中类的三种继承方式示例分享

Python如何删除字符串中所有空格

Python 怎么获取文件名

Python新手入门之环境安装

%s在Python中是什么意思

Python怎么把string变为hex

分享Python实现的二叉树定义与遍历

为何Python不好找工作

__init__ 在 Python 中的用法

更多相关阅读请进入《Python》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...