首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >多处理IOError:错误的消息长度

多处理IOError:错误的消息长度
EN

Stack Overflow用户
提问于 2015-06-15 04:23:15
回答 4查看 6.7K关注 0票数 21

在向map函数传递大参数时,我得到了一个IOError: bad message length。我怎样才能避免这种情况?当我设置N=1500或更大时出现错误。

代码是:

代码语言:javascript
运行
复制
import numpy as np
import multiprocessing

def func(args):
    i=args[0]
    images=args[1]
    print i
    return 0

N=1500       #N=1000 works fine

images=[]
for i in np.arange(N):
    images.append(np.random.random_integers(1,100,size=(500,500)))

iter_args=[]
for i in range(0,1):
    iter_args.append([i,images])

pool=multiprocessing.Pool()
print pool
pool.map(func,iter_args)

multiprocessing的文档中,有一个引发IOError的函数recv_bytes。会不会是因为这个原因?(https://python.readthedocs.org/en/v2.7.2/library/multiprocessing.html)

编辑如果我使用images作为数值数组而不是列表,我会得到一个不同的错误:SystemError: NULL result without error in PyObject_Call。稍有不同的代码:

代码语言:javascript
运行
复制
import numpy as np
import multiprocessing

def func(args):
    i=args[0]
    images=args[1]
    print i
    return 0

N=1500       #N=1000 works fine

images=[]
for i in np.arange(N):
    images.append(np.random.random_integers(1,100,size=(500,500)))
images=np.array(images)                                            #new

iter_args=[]
for i in range(0,1):
    iter_args.append([i,images])

pool=multiprocessing.Pool()
print pool
pool.map(func,iter_args)

EDIT2我实际使用的函数是:

代码语言:javascript
运行
复制
def func(args):
    i=args[0]
    images=args[1]
    image=np.mean(images,axis=0)
    np.savetxt("image%d.txt"%(i),image)
    return 0

此外,iter_args不包含相同的图像集:

代码语言:javascript
运行
复制
iter_args=[]
for i in range(0,1):
    rand_ind=np.random.random_integers(0,N-1,N)
    iter_args.append([i,images[rand_ind]])
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-08-13 05:58:29

这就是解决问题的方法:声明图像是全局的。

代码语言:javascript
运行
复制
import numpy as np
import multiprocessing


N=1500       #N=1000 works fine

images=[]
for i in np.arange(N):
    images.append(np.random.random_integers(1,100,size=(500,500)))

def func(args):
    i=args[0]
    images=images
    print i
    return 0

iter_args=[]
for i in range(0,1):
    iter_args.append([i])

pool=multiprocessing.Pool()
print pool
pool.map(func,iter_args)
票数 1
EN

Stack Overflow用户

发布于 2015-08-04 02:33:09

您正在创建一个池,并将所有图像一次发送到func()。如果您可以一次处理单个图像,可以尝试类似这样的操作,它将在35秒内运行到N=10000,并为我提供Python2.7.10:

代码语言:javascript
运行
复制
import numpy as np
import multiprocessing

def func(args):
    i = args[0]
    img = args[1]
    print "{}: {} {}".format(i, img.shape, img.sum())
    return 0

N=10000

images = ((i, np.random.random_integers(1,100,size=(500,500))) for i in xrange(N))
pool=multiprocessing.Pool(4)
pool.imap(func, images)
pool.close()
pool.join()

这里的关键是使用迭代器,这样你就不必一次在内存中保存所有的数据。例如,我将保存所有数据的数组中的图像转换为生成器表达式,以便仅在需要时创建图像。你可以修改它,从磁盘或其他任何地方加载你的图像。我也使用了pool.imap而不是pool.map。

如果可以,请尝试在worker函数中加载图像数据。现在,您必须序列化所有数据并将其传送到另一个进程。如果您的图像数据较大,这可能是一个瓶颈。

现在更新,我们知道func必须一次处理所有图像

你可以对你的图像做一个迭代均值。这里有一个不使用多进程的解决方案。要使用多处理,您可以将图像分成块,然后将这些块分配到池中。

代码语言:javascript
运行
复制
import numpy as np

N=10000
shape = (500,500)

def func(images):
    average = np.full(shape, 0)
    for i, img in images:
        average += img / N
    return average

images = ((i, np.full(shape,i)) for i in range(N))

print func(images)
票数 12
EN

Stack Overflow用户

发布于 2015-08-01 19:34:41

Python可能会将数据加载到RAM内存中,而您需要此内存可用。你检查过你的电脑内存使用情况了吗?

此外,正如Patrick提到的,您正在加载3 3GB的数据,请确保您使用的是64位版本的Python,因为您将达到32位内存限制。这可能会导致进程崩溃:32 vs 64 bits Python

另一个改进是使用python 3.4而不是2.7。Python3实现似乎针对非常大的范围进行了优化,请参阅Python3 vs Python2 list/generator range performance

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30834132

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档