Действительно ли это работает параллельно?

Я использую запросы и потоки в python, чтобы делать некоторые вещи. Мой вопрос: действительно ли этот код работает в многопоточном режиме и безопасно ли его использовать? Я испытываю некоторое замедление с течением времени. Примечание. Я не использую этот точный код, но мой делает похожие вещи.

import time
import requests

current_threads = 0
max_threads = 32


def doStuff():
    global current_threads
    r = requests.get('https://google.de')
    current_threads-=1


while True:
    while current_threads >= max_threads:
        time.sleep(0.05)

    thread = threading.Thread(target = doStuff)
    thread.start()

    current_threads+=1

Да, он работает с несколькими потоками. Было бы лучше, если бы вы использовали concurrent.futures.ThreadPoolExecutor с max_workers=max_threads. Код, который у вас есть, продолжает создавать новые потоки, что может быть причиной возможного замедления. Что касается безопасности, изменение такой общей переменной без чего-то вроде Lock для предотвращения одновременного доступа также может быть проблематичным и ненужным, если вы используете ThreadPoolExecutor.

martineau 31.05.2019 23:39

@martineau Сэр, могу я обратить ваше внимание на здесь и награда по аналогичной проблеме!

Mario 31.05.2019 23:58

@martineau Спасибо за ответ, но почему именно ThreadPoolExecutor лучше?

user10699450 01.06.2019 00:37

Брайан: Ну, навскидку, помимо того, что не требует изменения глобальных переменных потенциально небезопасным способом, он не создает неограниченного количества потоков, это отлаженный встроенный, написанный экспертами, и был разработан именно для того, чтобы делать добрые дела. кажется, вы пытаетесь.

martineau 01.06.2019 01:01

Брайан: Этот отвечать к другому вопросу также содержит хорошее объяснение того, как это лучше.

martineau 03.06.2019 11:39
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
71
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

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

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

    while current_threads >= max_threads:
        time.sleep(0.05)
    

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

  3. Проблема может быть не в вашем коде или вашей пропускной способности, а в сервере, с которого вы извлекаете файлы, если этот сервер перегружен, это может замедлить вашу передачу.

  4. Брандмауэры, IPS, IDS, политики на сервере могут ограничивать ваши запросы. Если вы сделаете слишком много запросов, чтобы быстро все с одного и того же IP-адреса, сетевое оборудование на стороне сервера может принять это за своего рода DoS-атаку и заблокировать ваши запросы в ответ.

  5. К сожалению, Python, по сравнению с другими языками более низкого уровня, такими как C# или C++, не так хорош в многопоточности. Это связано с тем, что называется GIL (глобальная блокировка интерпретатора), которая вступает в игру, когда вы получаете доступ к одним и тем же данным или манипулируете ими в нескольких потоках. Это довольно обширная тема сама по себе, но если вы хотите прочитать об этом, взгляните на эту ссылку.

https://medium.com/practo-engineering/threading-vs-multiprocessing-in-python-7b57f224eadb

Извините, я ничем больше не могу помочь, но это все, что я могу сказать по этому вопросу, учитывая предоставленную информацию.

Сэр, могу я обратить ваше внимание на здесь и награда по аналогичной проблеме!

Mario 31.05.2019 23:56

Конечно, вы используете несколько потоков и при условии, что они не обращаются к одним и тем же ресурсам или не изменяют их, вы, вероятно, «безопасны».

Всякий раз, когда я обращаюсь к внешним ресурсам (т. е. использую запросы), я всегда рекомендую asyncio, а не ванильную многопоточность, поскольку она позволяет переключать настраиваемый контекст (везде, где у вас есть «ожидание», вы переключаете контексты, тогда как в ванильном многопоточности переключение между потоками определяется ОС и может быть не оптимальным) и сократить накладные расходы (вы используете только ОДИН поток).

Сэр, могу я обратить ваше внимание на здесь и награда по аналогичной проблеме!

Mario 31.05.2019 23:57

Другие вопросы по теме