Многопроцессорная обработка очереди и возврат списка - PullRequest
1 голос
/ 20 марта 2020

Итак, я пытаюсь обработать очередь из двух почтовых индексов. Функция подачи очереди состоит в том, чтобы рассчитать проезд и прямое расстояние между двумя почтовыми индексами. Я хотел бы, чтобы функция возвращала оба значения (расстояние вождения и расстояние) и могла добавлять эти значения в список, чтобы я могла использовать их позже. Я довольно новичок в многопроцессорности, поэтому я не уверен, где отсюда go. Изначально я не был уверен, сможете ли вы передать два аргумента через пул / очередь, поэтому я решил попробовать поместить два почтовых индекса в набор, который будет передан через функцию, чтобы попытаться использовать его в качестве одного аргумента, а затем извлечь необходимые предметы отдельно. Пожалуйста, дайте мне знать, если вам нужна дополнительная информация от меня.

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()

1 Ответ

0 голосов
/ 20 марта 2020

A queue.Queue() не следует использовать для передачи аргументов pool работника. Вместо этого вы должны непосредственно передать итерируемое (например, список наборов аргументов) в 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() и pool.join(), что дает вам следующую часть код:

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

т.е. без явного close() или join() и без промежуточного списка почтовых индексов.

...