Простой многопоточный цикл в Python

Я искал везде и не нашел ни одного простого примера итерации цикла с многопоточностью.

Например, как я могу многопоточность этого цикла?

for item in range(0, 1000):
    print item

Есть ли способ разрезать его как 4 потока, чтобы каждый поток имел 250 итераций?

Ответ 1

Самый простой способ - использовать multiprocessing.dummy (в котором вместо процессов используются потоки) и пул.

import multiprocessing.dummy as mp 

def do_print(s):
    print s

if __name__=="__main__":
    p=mp.Pool(4)
    p.map(do_print,range(0,10)) # range(0,1000) if you want to replicate your example
    p.close()
    p.join()

Возможно, вы захотите попробовать настоящую многопроцессорность, если вы хотите лучше использовать несколько процессоров, но есть несколько предостережений и рекомендаций, которым необходимо следовать.

Возможно, другие методы Pool будут лучше соответствовать вашим потребностям - в зависимости от того, что вы на самом деле пытаетесь сделать.

Ответ 2

Вам нужно будет сделать расщепление вручную:

import threading

def ThFun(start, stop):
    for item in range(start, stop):
        print item

for n in range(0, 1000, 100):
    stop = n + 100 if n + 100 <= 1000 else 1000
    threading.Thread(target = ThFun, args = (n, stop)).start()

В этом коде используется многопоточность, что означает, что все будет выполняться в рамках одного процесса Python (т.е. будет запущен только один интерпретатор Python).

Многопроцессорность, обсуждаемая в другом ответе, означает запуск некоторого кода в нескольких интерпретаторах Python (в нескольких процессах, а не в потоках). Это может использовать все доступные ядра ЦП, поэтому это полезно, когда вы фокусируетесь на скорости вашего кода (печатайте тонну чисел, пока терминал не ненавидит вас!), А не просто при параллельной обработке. 1


1. multiprocessing.dummy оказывается оболочкой вокруг модуля threading. multiprocessing и multiprocessing.dummy имеют один и тот же интерфейс, но первый модуль выполняет параллельную обработку с использованием процессов, а второй - с использованием потоков.

Ответ 3

Это разделит ваш целевой список на куски и запустит отдельные потоки. Больше информации здесь:

import concurrent.futures

mybiglist=['abc','def','ghi','jkl','mno']
mytargetlist=['abc','jkl']

def get_index(x):
    return mybiglist.index(x)

with concurrent.futures.ProcessPoolExecutor() as executor:
    results = executor.map(get_index, mytargetlist)

print(list(results))