我试图多处理一些现有的代码,但我发现用Pool
对进程的数据进行pickle/unpickle太慢了。我认为对于我的情况,a Manager
也会遭受同样的问题,因为它在幕后也会做同样的事情。在
为了解决这个问题,我尝试转移到共享内存阵列。为了让它工作,我需要一个字符串数组。似乎multiprocessing.Array
支持ctypes.c_char_p
,但我很难将其扩展到字符串数组中。下面是我尝试过的许多方法中的一些。在
#!/usr/bin/python
import ctypes
import multiprocessing as mp
import multiprocessing.sharedctypes as mpsc
import numpy
# Tested possible solutions
ver = 1
if 1==ver:
strings = mpsc.RawArray(ctypes.c_char_p, (' '*10, ' '*10, ' '*10, ' '*10))
elif 2==ver:
tmp_strings = [mpsc.RawValue(ctypes.c_char_p, ' '*10) for i in xrange(4)]
strings = mpsc.RawArray(ctypes.c_char_p, tmp_strings)
elif 3==ver:
strings = []
for i in xrange(4):
strings.append( mpsc.RawValue(ctypes.c_char_p, 10) )
def worker(args):
snum, lenarg = args
string = '%s' % snum
string *= lenarg
strings[snum] = string
return string
# Main progam
data = [(i, numpy.random.randint(1,10)) for i in xrange(3)]
print 'Testing version ', ver
print
print 'Single process'
for x in map(worker, data):
print '%10s : %s' % (x, list(strings))
print
print 'Multi-process'
pool = mp.Pool(3)
for x in pool.map(worker, data):
print '%10s : %s' % (x, list(strings))
print ' ', [isinstance(s, str) for s in strings]
请注意,我使用multiprocessing.sharedctypes
,因为我不需要锁定,它应该可以与multiprocessing.Array
互换
上面代码的问题是结果strings
对象包含常规字符串,而不是来自mpsc.RawArray
构造函数的共享内存字符串。在版本1和版本2中,您可以看到在进程外工作时数据是如何被置乱的(如预期的那样)。对我来说,版本3看起来像是最初工作的,但是您可以看到=
只是将对象设置为一个常规字符串,虽然这对于短期测试有效,但在较大的程序中它会产生问题。在
似乎应该有一种方法来创建一个共享指针数组,其中指针指向共享内存空间中的字符串。如果您试图用c_str_p
类型初始化它,c_void_p
类型会抱怨,而我还没有机会直接操作底层地址指针。在
任何帮助都将不胜感激。在
首先,您的第三个解决方案不起作用,因为
strings
不是由多处理部分更改的,而是由单个进程部分修改的。您可以通过注释您的单个流程部分来进行检查。在第二,这个方法会起作用:
输出:
^{pr2}$相关问题 更多 >
编程相关推荐