多处理字符串共享内存数组

2024-10-02 22:37:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图多处理一些现有的代码,但我发现用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类型会抱怨,而我还没有机会直接操作底层地址指针。在

任何帮助都将不胜感激。在


Tags: 字符串inimportforstring数组ctypesmultiprocessing
1条回答
网友
1楼 · 发布于 2024-10-02 22:37:29

首先,您的第三个解决方案不起作用,因为strings不是由多处理部分更改的,而是由单个进程部分修改的。您可以通过注释您的单个流程部分来进行检查。在

第二,这个方法会起作用:

import ctypes
import multiprocessing as mp
import multiprocessing.sharedctypes as mpsc
import numpy

strings = [mpsc.RawArray(ctypes.c_char, 10) for _ in xrange(4)]

def worker(args):
    snum, lenarg = args
    string = '%s' % snum
    string *= lenarg
    strings[snum].value = string
    return string

# Main progam
data = [(i, numpy.random.randint(1,10)) for i in xrange(4)]

print 'Multi-process'
print "Before: %s" % [item.value for item in strings]
pool = mp.Pool(4)
pool.map(worker, data)
print 'After : %s' % [item.value for item in strings]

输出:

^{pr2}$

相关问题 更多 >