Python обрабатывает большое количество потоков?

# data is a list  

Threading_list=[]

class myfunction(threading.Thread):

    def __init__(self,val):
        .......
    .......

     def run(self):
        .......
        ....... 

for i in range(100000):

    t=myfunction(data[i]) # need to execute this function on every datapoint 
    t.start()
    Threading_list.append(t)

for t in Threading_list:
    t.join()

Это создаст около 100000 потоков, но мне разрешено создавать максимум 32 потока? Какие изменения могут быть сделаны в этом коде?

2 ответа

Решение

Так много потоков Python редко нужно создавать. Более того, я едва ли могу себе представить причину этого. Существуют подходящие архитектурные шаблоны для решения задач создания кода, выполняемого параллельно, которые ограничивают количество потоков. Одним из них является реактор.

Что ты пытаешься сделать?

И помните, что благодаря GIL потоки Python не дают никакого повышения производительности для вычислительных задач, даже в многопроцессорных системах и системах с несколькими ядрами (кстати, может ли быть система с 100000 ядрами? Я сомневаюсь.:)). Единственный шанс для повышения, если вычислительная часть выполняется внутри модулей, написанных на C/C++, которые выполняют свою работу без получения GIL. Обычно потоки Python используются для параллельного выполнения кода, который содержит блокирующие операции ввода-вывода.

UPD: заметил тэг stackless-python. AFAIK, он поддерживает микропотоки. Тем не менее, до сих пор неясно, что вы пытаетесь сделать.

И если вы пытаетесь просто обработать 100000 значений (применить формулу к каждому из них?), Лучше написать что-то вроде:

def myfunction(val):
    ....
    return something_calculated_from_val

results = [myfunction(d) for d in data] # you may use "map(myfunction, data)" instead

Это должно быть намного лучше, если myfunction() выполняет некоторый блокирующий ввод / вывод. Если это так, ThreadPoolExecutor может действительно помочь

Вот пример, который будет вычислять квадраты списка любой длины, используя 32 потока через ThreadPoolExecutor. Как сказал Эллиох, в некоторых случаях вы можете не использовать потоки, поэтому вы можете легко переключиться на ProcessPoolExecutor.

import concurrent.futures

def my_function(x):
    return 2**x

data = [1, 6, 9, 3, 8, 4, 213, 534]

with concurrent.futures.ThreadPoolExecutor(max_workers=32) as executor:
    result = list(executor.map(my_function, data))

print(result)
Другие вопросы по тегам