Влияние сотен бездействующих потоков - PullRequest
8 голосов
/ 03 ноября 2010

Я рассматриваю возможность использования сотен потоков для реализации задач, которые управляют устройствами по сети.

Это приложение C ++, работающее на процессоре PowerPC с ядром Linux.

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

Итак, моя главная проблема в том, что, если у меня будут сотни потоков, они негативно отразятся наСистема, когда они простаивают?

Спасибо.amso

edit:
Я обновляю вопрос, основываясь на полученных ответах.Спасибо, парни.Таким образом, кажется, что наличие массы бездействующих потоков (блокировка ввода-вывода, ожидание, спящий режим и т. Д.), per se , не повлияет на систему с точки зрения скорости отклика.Конечно, они будут тратить дополнительные деньги на стек каждого потока и данные TLS, но это нормально, пока мы добавляем больше памяти (что делает ее более выгодной)

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

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

Я думаю, это все.Спасибо всем за их вклад.

-
Амсо

Ответы [ 6 ]

8 голосов
/ 03 ноября 2010

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

3 голосов
/ 03 ноября 2010

В основном они будут использовать адресное пространство и память для стеков; как только вы получите, скажем, 1000 потоков, это становится довольно значительным, поскольку я видел, что 10M на поток типично для стеков (на x86_64). Он изменчив, но только с осторожностью.

Если у вас 32-битный процессор, адресное пространство будет основным ограничением, когда вы попадете на 1000 потоков, вы можете легко исчерпать AS.

Они занимают немного памяти ядра, но, вероятно, не так много, как пространство пользователя.


Редактировать: конечно, потоки разделяют адресное пространство друг с другом, только если они находятся в одном процессе; Я предполагаю, что они есть.

2 голосов
/ 03 ноября 2010

Я бы побеспокоился о том, чтобы предлагать сопоставления потоковых соединений 1: 1, если не что иное, потому что это скорее делает вас уязвимыми для атак типа «отказ в обслуживании».(pthread_create() является довольно дорогой операцией по сравнению с просто вызовом accept())

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

1 голос
/ 03 ноября 2010

Я не хакер Linux, но при условии, что планирование потоков в Linux похоже на Windows '...

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

Однако в среде с временными интервалами потоки, находящиеся в состоянии ожидания / ожидания / соединения, не будут потреблять циклы ЦП, пока они не будут активированы.

0 голосов
/ 05 января 2011

Я не уверен, о каком «устройстве» вы говорите, но если это дескриптор файла, я бы посоветовал вам взглянуть на начало перехода на использование опроса или epoll (я бы предложил последнее, учитывая описаниенасколько активно вы ожидаете, что каждый дескриптор файла будет).Таким образом, вы можете использовать один процесс, который будет отвечать за все fds.

0 голосов
/ 03 ноября 2010

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

Linux реализует каждый поток POSIX как уникальный процесс.Это создаст накладные расходы, как уже упоминали другие.В дополнение к этому, ваша ожидающая модель выглядит некорректно, как бы вы это ни делали.Если вы создадите одну условную переменную для каждого потока, то я думаю (исходя из моей интерпретации сайта ниже), что вы на самом деле будете тратить много памяти на ядро, так как каждый поток будет помещен в свою очередь ожидания.Если вместо этого вы разделяете свои потоки для каждой группы потоков X для совместного использования условной переменной, то у вас также возникают проблемы, потому что каждый раз, когда переменная сигнализирует, вы должны пробуждаться _EVERY_DARN_PROCESS_ в очереди ожидания этой переменной.* Я также предполагаю, что вам нужно будет выполнить синхронизацию между некоторыми объектами.В этом случае ваш код может работать медленнее из-за необходимости пробуждать все процессы, ожидающие ресурса, как я упоминал ранее.

Я знаю, что это не сильно помогло, но, как я уже сказал, я 'ядро нуб.Надеюсь, это немного помогло.

http://book.chinaunix.net/special/ebook/PrenticeHall/PrenticeHallPTRTheLinuxKernelPrimer/0131181637/ch03lev1sec7.html

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