首页 > 解决方案 > 多处理一个队列并返回一个列表

问题描述

所以我正在尝试处理两个邮政编码的队列。队列被送入的功能是计算两个邮政编码之间的行驶距离和直线距离。我希望该函数返回两个值(行驶距离和直线距离)并能够将这些值附加到列表中,以便以后使用它们。我对多处理相当陌生,所以我不确定从这里去哪里。我最初不确定您是否可以通过池/队列传递两个参数,所以我决定尝试将两个邮政编码放入一组以通过函数传递以尝试将其用作一个参数,然后拉出必要的物品分开。如果您需要我提供更多信息,请告诉我。

doc_num = []
origin_zip = []
origin_add = []
origin_city = []

destin_zip = []
destin_add = []
destin_city = []


#for i in range(14, len(data)-1):
for i in range(14, 16):   
    doc_num.append(data['AutoTable+Fit.13'][i])

    origin_add.append(data['AutoTable+Fit'][i])
    origin_city.append(data['AutoTable+Fit.1'][i])
    origin_zip.append(data['AutoTable+Fit.2'][i])

    destin_add.append(data['AutoTable+Fit.8'][i])
    destin_city.append(data['AutoTable+Fit.6'][i])
    destin_zip.append(data['AutoTable+Fit.7'][i])

distances = []

def calculate_distances(q):

        try:    
            zip_sets = q.get()
            drive = (gmaps.distance_matrix(zip_sets[1][0], zip_sets[1][1]))['rows'][0]['elements'][0]['distance']['value'] * 0.000621371
            #print(f"Driving distance:", drive_dist)

            LAT1 = gmaps.geocode(zip_sets[1][0])[0]['geometry']['location']['lat']
            LONG1 = gmaps.geocode(zip_sets[1][0])[0]['geometry']['location']['lng']
            LAT2 = gmaps.geocode(zip_sets[1][1])[0]['geometry']['location']['lat']
            LONG2 = gmaps.geocode(zip_sets[1][1])[0]['geometry']['location']['lng']

            distance = math.acos(math.cos(math.radians(90-(LAT1))) *math.cos(math.radians(90-(LAT2))) + math.sin(math.radians(90-(LAT1)))\
                                 * math.sin(math.radians(90-(LAT2))) * math.cos(math.radians((LONG1)-(LONG2)))) * 3958.756

        except:

            drive = -1
            distance = -1

        return (drive, distance)

q = Queue()

for x in range(len(origin_zip)):
    q.put((origin_zip[x], destin_zip[x]))

pool = Pool(5)
pool.map(calculate_distances, (q,))
pool.close()
pool.join()

标签: pythonmultiprocessingqueue

解决方案


Aqueue.Queue()不应用于将参数传递给 a poolof worker。相反,您应该直接将一个可迭代的(例如参数集的列表)传递给pool.map()

# Create a list of pairs as input to pool.map() (Not needed, see below)
pairs = [pair for pair in zip(origin_list, destin_list)]
distances = pool.map(calculate_distances, pairs)
pool.close()
pool.join()

但是,pairs在这种情况下,不需要创建列表,因为zip操作的输出无论如何都是可迭代的,可以直接使用。此外,如果您正在运行 Python 3.3 或更高版本(我真诚地希望您这样做),您应该考虑使用上下文管理器 ( with ...) 而不是pool.close()andpool.join()调用,为您提供以下代码:

with Pool(5) as pool:
    distances = pool.map(calculate_distances, zip(origin_list, destin_list))

即,没有明确的close()join()没有邮政编码的中间列表。


推荐阅读