Максимальное безопасное количество потоков для запуска сразу [дубликат]

Ответы на основе метакласса по-прежнему работают в Python3, но вместо атрибута __metaclass__ нужно использовать параметр metaclass, как в:

class ExampleTestCase(TestCase,metaclass=DocTestMeta):
    pass
257
задан fncomp 17 September 2014 в 00:14
поделиться

12 ответов

Некоторые люди скажут, что двух потоков слишком много - я не совсем в этом лагере: -)

Вот мой совет: measure, don ' Предположим, что должно быть настроено и изначально установить его на 100, затем отпустите свое программное обеспечение в дикое состояние и проверьте, что произойдет.

Если ваше использование потока достигает максимума 3, тогда 100 слишком много. Если он остается на уровне 100 в течение большей части дня, увеличьте его до 200 и посмотрите, что произойдет.

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

Для пояснения и уточнения:

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

которые я считаю необходимыми для производительности):

  • минимальное количество активных потоков.
  • максимум число нитей.
  • завершение потоков, которые не использовались некоторое время.

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

Вам необходимо сбалансировать использование ресурсов, когда неиспользуемые потоки (A) используются для использования ресурсов, не имея достаточного количества потоков для выполнения work (B).

(A) - это, как правило, использование памяти (стеки и т. д.), поскольку поток, не выполняющий работу, не будет использовать большую часть процессора. (B), как правило, является задержкой в ​​обработке запросов по мере их поступления, поскольку вам нужно ждать, пока поток станет доступным.

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

Во-первых, количество доступных соединений DB. Это может быть жестким пределом, если вы не можете увеличить его в СУБД - я собираюсь предположить, что ваша СУБД может принимать неограниченное количество соединений в этом случае (хотя в идеале вы также должны это измерить).

Затем количество потоков, которые вы должны зависеть от вашего исторического использования. Минимальный минимум, который у вас должен иметь бег, - это минимальное количество, которое у вас когда-либо имело + A%, с абсолютным минимумом (например, и сделать его настраиваемым точно так же, как A) 5.

Максимальное число нитей должен быть вашим историческим максимумом + B%.

Вы также должны отслеживать изменения поведения. Если по какой-либо причине ваше использование переходит на 100% доступного в течение значительного времени (так, чтобы это повлияло на производительность клиентов), вы должны увеличить максимальное допустимое значение до тех пор, пока оно снова не B% выше.

< hr>

В ответ на «что именно я должен измерить?» вопрос:

То, что вы должны конкретно определить, - это максимальное количество потоков при одновременном использовании (например, ожидание возврата из вызова БД) под нагрузкой. Затем добавьте коэффициент безопасности 10% для примера (подчеркнуто, поскольку другие плакаты, кажется, принимают мои примеры в качестве фиксированных рекомендаций).

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

170
ответ дан paxdiablo 24 August 2018 в 23:56
поделиться

Если ваши потоки выполняют какую-либо ресурсоемкую работу (CPU / Disk), вы редко увидите преимущества за пределами одного или двух, и слишком многие быстро убьют производительность.

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

Хорошим решением является размещение запросов в пуле, которые затем отправляются в рабочие потоки из потока -pool (и да, избегая непрерывного создания / разрушения резьбы - отличный первый шаг).

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

15
ответ дан Andrew Grant 24 August 2018 в 23:56
поделиться

Как правильно сказал Пакс, измерьте, не догадывайтесь. Это то, что я сделал для DNSwitness , и результаты были удивительными: идеальное количество потоков было намного выше, чем я думал, примерно 15 000 потоков, чтобы получить самые быстрые результаты.

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

Полные меры (только на французском языке) в Combien de fils d'exécution? .

7
ответ дан bortzmeyer 24 August 2018 в 23:56
поделиться

Следует иметь в виду, что python (по крайней мере, на основе C) использует то, что называется глобальным интерпретатором , которое может иметь огромное влияние на производительность на многоядерных машинах.

Если вам действительно нужна большая часть многопоточного питона, вам может потребоваться использовать Jython или что-то в этом роде.

9
ответ дан Chad Okere 24 August 2018 в 23:56
поделиться

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

Вы можете найти более подробную информацию о том, как это должно работать здесь : http://en.wikipedia.org/wiki/Thread_pool_pattern

-6
ответ дан GEOCHET 24 August 2018 в 23:56
поделиться

Ответ на «большой железо» - это, как правило, один поток на один ограниченный ресурс - процессор (привязка к ЦП), рука (привязка ввода / вывода) и т. д. - но это работает только в том случае, если вы можете перенаправить работу на нужную нить для доступ к ресурсу.

Если это невозможно, считайте, что у вас есть взаимозаменяемые ресурсы (ЦП) и неисправимые ресурсы (оружие). Для процессоров не важно назначать каждый поток конкретному процессору (хотя он помогает в управлении кешем), но для оружия, если вы не можете назначить нить в руку, вы попадаете в теорию массового обслуживания и оптимальное количество, чтобы держать оружие занятый. В общем, я думаю, что если вы не можете направлять запросы на основе используемой руки, то будет иметься 2-3 потока на руку.

Усложнение возникает, когда единица работы переданный в поток, не выполняет разумно атомную единицу работы. Например, у вас может быть поток в одной точке доступа к диску, в другой точке ждут в сети. Это увеличивает количество «трещин», где дополнительные потоки могут проникать и делать полезную работу, но это также увеличивает возможность добавления дополнительных потоков для загрязнений кэшей друг друга и т. Д. И путаницу системы.

Of Конечно, вы должны взвесить все это против «веса» нити. К сожалению, большинство систем имеют очень тяжелые потоки (и то, что они называют «легкими потоками», часто не являются нитями вообще), поэтому лучше ошибиться на низкой стороне.

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

3
ответ дан Hot Licks 24 August 2018 в 23:56
поделиться

ryeguy, я в настоящее время разрабатываю аналогичное приложение, а число моих потоков равно 15. К сожалению, если я увеличиваю его на 20, он сработает. Итак, да, я считаю, что лучший способ справиться с этим - измерить, разрешает ли ваша текущая конфигурация больше или меньше числа X потоков.

1
ответ дан hyperboreean 24 August 2018 в 23:56
поделиться

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

  1. Размер стека в потоке: в Linux размер стека по умолчанию составляет 8 МБ (вы можете использовать ulimit -a, чтобы узнать его).
  2. Макс. Виртуальная память, поддерживаемая данным вариантом ОС. Linux Kernel 2.4 поддерживает адресное пространство памяти 2 ГБ. с ядром 2.6, я немного больше (3 ГБ)
  3. [1] показывает расчеты для максимального количества потоков при заданной максимальной поддержке VM. Для 2.4 получается около 255 потоков. для 2.6 число немного больше.
  4. Какой у вас планировщик ядра kernel? Сравнивая планировщик ядра Linux 2.4 с 2.6, более поздний дает вам планирование O (1), не зависящее от количества задач, существующих в системе, в то время как первый из них больше O (n). Таким образом, возможности SMP в графике ядра также играют хорошую роль в максимальном количестве устойчивых потоков в системе.

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

Обратите внимание, что при его желании можно создавать тысячи потоков, но когда Linux заканчивается из VM, он просто случайно запускает процессы уничтожения (таким образом, потоки). Это означает, что профиль полезности не будет превышен. (Функция полезности сообщает об утилите всей системы для заданного количества ресурсов. С постоянными ресурсами в этом случае CPU Cycles and Memory кривая полезности сглаживается с большим количеством задач).

I я уверен, что планировщик ядра Windows также делает что-то подобное для борьбы с использованием ресурсов

[1] http://adywicaksono.wordpress.com/2007/07/10/i- может-не-создавать-более, чем 255-нитей-на-Linux-что-это-The-решения /

26
ответ дан Jay D 24 August 2018 в 23:56
поделиться

Поскольку многие потоки, такие как ядра CPU, я слышал очень часто.

-10
ответ дан masfenix 24 August 2018 в 23:56
поделиться

Я написал несколько многопоточных приложений. Обычно я допускаю, чтобы количество потенциальных потоков определялось конфигурационным файлом. Когда я настроился на конкретных клиентов, я установил число, достаточно высокое, что мое использование всех ядер процессора было довольно высоким, но не настолько высоким, что я столкнулся с проблемами памяти (это были 32-разрядные операционные системы на время].

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

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

4
ответ дан Matthew Lund 24 August 2018 в 23:56
поделиться

Я думаю, что это немного уловка на ваш вопрос, но почему бы не разветвить их на процессы? Мое понимание сетевого взаимодействия (из туманных дней, на самом деле, я вообще не кодирую сети) заключалось в том, что каждое входящее соединение можно обрабатывать как отдельный процесс, потому что если кто-то делает что-то неприятное в вашем процессе, nuke всю программу.

2
ответ дан mmr 24 August 2018 в 23:56
поделиться

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

2
ответ дан newdayrising 24 August 2018 в 23:56
поделиться