Сотни тысяч на Go Часто задаваемые вопросы: Почему вместо потоков используются программы? :
Практично создавать сотни тысяч программ в одном и том же адресном пространстве.
Тест test / chan / goroutines.go создает 10000 и может легко сделать больше, но предназначен для быстрой работы;Вы можете изменить номер в вашей системе, чтобы экспериментировать.Вы можете легко запустить миллионы при наличии достаточного объема памяти, например на сервере.
Чтобы понять максимальное количество процедур, обратите внимание, что стоимость каждой процедуры - это, прежде всего, стек.Снова в разделе часто задаваемых вопросов:
… подпрограммы могут быть очень дешевыми: они имеют небольшие накладные расходы помимо стека, занимающего всего несколько килобайт.
A назадпри вычислении конверта предполагается, что для каждой подпрограммы выделена одна 4 КиБ страница , выделенная для стека (4 КиБ - довольно равномерный размер), плюс небольшие накладные расходы для блока управления (например, Блок управления потоком ) для времени выполнения;это согласуется с тем, что вы наблюдали (в 2011 году, pre-Go 1.0).Таким образом, подпрограммы на 100 Ки занимают около 400 МБ памяти, а подпрограммы на 1 Ми занимают около 4 ГБ памяти, которые по-прежнему управляемы на настольном компьютере, немного для телефона и очень управляемы на сервере.На практике размер стартового стека варьируется от половины страницы (2 КиБ) до двух страниц (8 КиБ), поэтому это примерно правильно.
Размер стартового стека со временем менялся;он начинался с 4 КиБ (одна страница), затем в 1,2 был увеличен до 8 КиБ (2 страницы), затем в 1,4 был уменьшен до 2 КиБ (половина страницы).Эти изменения произошли из-за сегментированных стеков, вызывающих проблемы с производительностью при быстром переключении между сегментами («горячее разделение стеков»), поэтому они были увеличены, чтобы смягчить (1.2), а затем уменьшились, когда сегментированные стеки были заменены смежными стеками (1.4):
Go 1.2 Примечания к выпуску: Размер стека :
В Go 1.2 минимальный размер стека при создании программы был увеличен с 4 КБ до 8 КБ
Go 1.4 Примечания к выпуску: Изменения во время выполнения :
начальный размер по умолчанию для стека goroutine в 1.4 был уменьшен с 8192 байтов до2048 байт.
Память для каждой программы в основном стековая, и она начинается с низкого уровня и растет, так что вы можете дешево иметь много процедур.Вы могли бы использовать меньший начальный стек, но тогда он должен был бы расти быстрее (выиграть пространство за счет затрат времени), и преимущества уменьшились бы из-за того, что блок управления не сжимался.Возможно исключить стек, по крайней мере, при его замене (например, сделать все выделения в куче или сохранить стек в куче при переключении контекста), хотя это снижает производительность и увеличивает сложность.Это возможно (как в Erlang) и означает, что вам просто понадобится блок управления и сохраненный контекст, позволяющий еще один коэффициент в 5 × –10 × по числу процедур, который теперь ограничен размером блока управления и размером подпрограммы в куче.локальные переменныеТем не менее, это не очень полезно, если только вам не нужны миллионы крошечных спящих программ.
Поскольку основное использование множества программ предназначено для задач, связанных с вводом-выводом (конкретно для обработки блокирующих системных вызовов, особенно сети или файловой системы).IO), у вас гораздо больше шансов столкнуться с ограничениями ОС для других ресурсов, а именно сетевых сокетов или файловых дескрипторов: golang-nuts ›Максимальное количество процедур и дескрипторов файлов? .Обычный способ решения этой проблемы - с помощью пула дефицитного ресурса или, проще, просто ограничив число с помощью семафора ;см. Сохранение файловых дескрипторов в Go и Ограничение параллелизма в Go .