Найти - Пользователи
Полная версия: проблема в многопоточном скрипте
Начало » Python для новичков » проблема в многопоточном скрипте
1
robisho
Добрый день. Многопоточный скрипт перебирает данные из списка mail_lst, работает норм, но если в него запихать список длиннее 665-670 строк - получается ошибка RuntimeError: can't start new thread.
 semaphore = threading.BoundedSemaphore(S_THREADS)
thr_lst = []
for index, mail in enumerate(mail_lst, 1):
    try:
        thr = threading.Thread(
            target=main,
            args=(mail, index, semaphore),
            daemon=True
        )
        thr_lst.append(thr)
        thr.start()
    except Exception as ex:
        logger.exception(f"Index={index} >>> {ex}")
for i_thr in thr_lst:
    i_thr.join(10.0)

помогите, пожалуйста, понять, почему так происходит и как это можно пофиксить? спасибо.
xam1816
почему именно потоки, а не асинхронно?. Многопоточность дает преимущество если потоков мало, потому что на переключение между потоками уходит время, чем больше потоков, тем больше переключений. Может лучше сделать асинхронно. Опиши кратко задачу что нужно сделать.
robisho
xam1816
почему именно потоки, а не асинхронно?. Многопоточность дает преимущество если потоков мало, потому что на переключение между потоками уходит время, чем больше потоков, тем больше переключений. Может лучше сделать асинхронно. Опиши кратко задачу что нужно сделать.

асинхронно можно, конечно, сделать. хочется понять, почему вылазит ограничение по потокам у меня. ни разу не ловил такой баг. может быть это только у меня случается? а задача - выбрать по майл:пасс доступные smtp.
py.user.next
robisho
Многопоточный скрипт перебирает данные из списка mail_lst, работает норм, но если в него запихать список длиннее 665-670 строк - получается ошибка RuntimeError: can't start new thread.
В питоне нет многопоточности. Многопоточность в питоне делается через один поток, который изображает из себя несколько потоков. Поэтому тебе надо разделить общий список на несколько списков и каждый из этих полученных списков обрабатывать в отдельном потоке, чтобы потоков там было штук десять, не больше.

robisho
помогите, пожалуйста, понять, почему так происходит и как это можно пофиксить?
Да это всё фикция, все эти семафоры и тому подобное. В питоне эта проблема заложена изначально в архитектуре. И от неё уже десятилетиями избавиться не могут.
robisho
убрал семафор и добавил промежуточный список. теперь сразу набирается пулл, а потом выдаются результаты, если они есть.

 temp_mail_lst = []
for index, mail in enumerate(mail_lst, 1):
    temp_mail_lst.append((index, mail))
    if len(temp_mail_lst) == S_THREADS or (index == len(mail_lst)):
        thr_lst = []
        for element in temp_mail_lst:
            index, mail = element[0], element[1]
            thr = threading.Thread(
                target=main,
                args=(mail, index),
                daemon=True
            )
            thr_lst.append(thr)
            thr.start()
        for i_thr in thr_lst:
            i_thr.join(10.0)
        temp_mail_lst = []

S_THREADS - это количество потоков, выбирается при запуске.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB