在Python中尝试对需要列表参数的函数进行多进程处理

0 投票
2 回答
1133 浏览
提问于 2025-04-28 10:31

我的问题是,我想把一个 list 作为变量传给一个函数,并希望能让这个函数同时处理多个任务。但我发现 pool.map 不能用,因为它只接受可迭代的对象。然后我又试了 pool.apply,但它在工作的时候会把整个池子都堵住,所以我不太明白它怎么能实现多线程(老实说,我对多线程的理解也不太深)。我还尝试了 pool.apply_async,但程序几秒钟就结束了,似乎只处理了大约 20000 次计算。以下是一些伪代码。

import MySQLdb
from multiprocessing import Pool

def some_math(x, y):
    f(x[1], x[2], y[1], y[2])
    return f

def distance(x):
    x_distances = []
    for y in all_y:
        distance = some_math(x, y)
        if distance > 1000000:
            continue
        else:
            x_distances.append(x[0], y[0],distance)
        mysql.executemany(sql_update, x_distances)
        mydb.commit()

all_x = []
all_y = []
sql_x = 'SELECT id, lat, lng FROM table'
sql_y = 'SELECT id, lat, lng FROM table'
sql_update = 'INSERT INTO distances (id_x, id_y, distance) VALUES (%s, %s, %S)'

cursor.execute(sql_x)
all_x = cursor.fetchall()

cursor.execute(sql_y)
all_y = cursor.fetchall()

p = Pool(4)
for x in all_x:
    p.apply_async(distance, x)

或者,如果使用 map:

p = Pool(4)
for x in all_x:
    p.map(distance, x)

错误信息是:

正在处理 A 的距离...

Traceback (most recent call last):
  File "./distance-house.py", line 94, in <module>
    p.map(range, row)
  File "/usr/lib/python2.7/multiprocessing/pool.py", line 251, in map
    return self.map_async(func, iterable, chunksize).get()
  File "/usr/lib/python2.7/multiprocessing/pool.py", line 558, in get
    raise self._value
TypeError: 'float' object has no attribute '__getitem__'

我想要多线程处理一个很长的计算——计算大约 10,000 个点之间的距离,很多对很多的关系。目前,这个过程要花好几天时间,我觉得如果能用多进程来处理结果,效率会大大提高。我很乐意听取建议。

暂无标签

2 个回答

0

另一种方法是把你的变量放在一个元组里,然后在函数内部把它们取出来。
举个例子:

def Add(z):
  x,y = z
  return x + y

a = [ 0 , 1, 2, 3]
b = [ 5, 6, 7, 8]
ab = (a,b)

Add(ab)
1

你可以使用 pool.map

p = Pool(4)
p.map(distance, all_x)

就像在文档中的第一个例子那样。它会为你自动处理循环!

撰写回答