Как получить номер элемента списка, обрабатываемого мультипотоком в python?

Есть список links, который обрабатывается:

with ThreadPoolExecutor(max_workers=num_threads) as pool:
    pool.map(my_func(links))

Подскажите, как в самой функции my_func я могу получить порядковый номер обрабатываемого элемента?


Ответы (1 шт):

Автор решения: CrazyElf

Наверное, вы всё-таки имели в виду такой код, а то у вас получается один поток вызывается и в один вызов функции передаётся весь список. А нужно передавать ссылки по отдельности:

pool.map(my_func, links)

Тогда можно воспользоваться enumerate:

pool.map(my_func, enumerate(links))

Только в функции my_func нужно будет распаковать кортеж (номер,link), пришедший в виде аргумента:

def my_func(tuple_):
    i, link = tuple_
    ...

Вот вам код, с помощью которого вы можете убедиться, что с вашим кодом вы просто вызываете сразу функцию и передаёте результат её работы в pool.map, он на это не ругается, но и ничего не делает. Чтобы реально задействовать потоки вам нужно передавать функцию и список аргументов отдельными параметрами:

from concurrent.futures import ThreadPoolExecutor
import threading
from time import sleep

def my_func(tuple_):
    i, link = tuple_
    print(threading.get_ident())
    print(i, link)
    sleep(0.5)
    
def my_f(x):
    print(threading.get_ident())
    print(x)

links = [1,2,3]
print(threading.get_ident())
with ThreadPoolExecutor(max_workers=4) as pool:
    pool.map(my_f(links))
    pool.map(my_func, enumerate(links))

Вывод:

140232952104768
140232952104768
[1, 2, 3]
140231703070464
0 1
140231711463168
1 2
140232015980288
2 3

Как видно, первый вызов my_f(links) выполняется в потоке с тем же номером, что и сам скрипт. То есть многопоточность вообще не используется. А вот второй вариант вызова делится на несколько потоков. Паузу я поставил специально, без неё он иногда успевает отдать один и тот же поток нескольким циклам обработки (иногда даже все три запроса выполняются в одном переиспользуемом потоке). Но в любом случае это будет другой поток, не основной, как в вашем коде.

→ Ссылка