如何在 Python 中使用 Managers() 在多个进程之间共享字符串?
Posted
技术标签:
【中文标题】如何在 Python 中使用 Managers() 在多个进程之间共享字符串?【英文标题】:How to share a string amongst multiple processes using Managers() in Python? 【发布时间】:2014-02-12 23:38:24 【问题描述】:我需要从主进程中读取由 multiprocessing.Process 实例编写的字符串。我已经使用管理器和队列将参数传递给进程,所以使用管理器似乎很明显,but Managers do not support strings:
Manager() 返回的管理器将支持类型列表、字典、 命名空间、锁、RLock、信号量、有界信号量、条件、事件、 队列、值和数组。
如何使用多处理模块中的管理器共享由字符串表示的状态?
【问题讨论】:
【参考方案1】:multiprocessing 的 Manager 可以保存 Values,而后者又可以保存 ctypes 模块中 c_char_p 类型的实例:
>>> import multiprocessing
>>> import ctypes
>>> v = multiprocessing.Value('c', "Hello, World!")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/multiprocessing/__init__.py", line 253, in Value
return Value(typecode_or_type, *args, **kwds)
File "/usr/lib/python2.7/multiprocessing/sharedctypes.py", line 99, in Value
obj = RawValue(typecode_or_type, *args)
File "/usr/lib/python2.7/multiprocessing/sharedctypes.py", line 73, in RawValue
obj.__init__(*args)
TypeError: one character string expected
>>> cstring = multiprocessing.Value(ctypes.c_char_p, "Hello, World!")
>>> cstring
<Synchronized wrapper for c_char_p(166841564)>
>>> cstring.value
'Hello, World!'
对于 Python 3, 使用 c_wchar_p 代替 c_char_p
另请参阅:Post with the original solution,我很难找到。
因此,可以使用 Manager 在 Python 中的多个进程下共享字符串,如下所示:
>>> from multiprocessing import Process, Manager, Value
>>> from ctypes import c_char_p
>>>
>>> def greet(string):
>>> string.value = string.value + ", World!"
>>>
>>> if __name__ == '__main__':
>>> manager = Manager()
>>> string = manager.Value(c_char_p, "Hello")
>>> process = Process(target=greet, args=(string,))
>>> process.start()
>>> process.join()
>>> print string.value
'Hello, World!'
【讨论】:
我想知道为什么会这样(共享指针),并且从消息来源中我了解到managers.Value
实际上根本没有使用typecode
参数。该字符串不会转换为c_char_p
。 multiprocessing.Value
的工作方式非常不同。
我试过s = multiprocessing.Value(c_char_p, "old string")
但s.value = "new string"
经常丢失指针。我还尝试了另一种更稳定的Array('c', fixed_length)
解决方案。
如果你试图摆脱Manager
,它不会起作用,因为c_wchar_p
只是一个指向数据的指针,所以当另一个进程访问它时,它会直接转到@987654336 @。更多解释可以在这里找到:***.com/a/12343115/3300539。是的,正如之前的评论中提到的,Array('c', fixed_length)
也适用于我。【参考方案2】:
只需将字符串放入dict
:
d = manager.dict()
d['state'] = 'xyz'
由于字符串本身是不可变的,因此直接共享一个不会有用。
【讨论】:
manager.dict()
速度较慢,因为它返回一个代理,并且代理总是将数据从一个线程复制到另一个线程,而multiprocessing.Value()
速度更快,因为它返回一个实际的共享内存区域,该区域只是直接访问的每个进程。以上是关于如何在 Python 中使用 Managers() 在多个进程之间共享字符串?的主要内容,如果未能解决你的问题,请参考以下文章