Существует ли проблема «Гремящего стада» в Linux? - PullRequest
30 голосов
/ 06 февраля 2010

Во многих книгах и руководствах по программированию на linux / unix говорится о «проблеме громового стада» , которая возникает, когда несколько потоков или вилок блокируются при вызове select (), ожидающем читаемости прослушивающего сокета. Когда соединение приходит, все потоки и вилки просыпаются, но только один «выигрывает» при успешном вызове «accept ()». Между тем, много времени процессора тратится впустую, разбудив все нити / разветвления без причины.

Я заметил проект , который предоставляет "исправление" для этой проблемы в ядре Linux, но это очень старый патч.

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

У современных ядер Unix / Linux все еще есть проблема Thundering Herd в обоих этих случаях или только версия "select () then accept ()"?

Ответы [ 4 ]

10 голосов
/ 11 апреля 2014

В течение многих лет большинство ядер unix / linux сериализуют ответ на accept (2), иными словами, пробуждается только один поток, если более одного блокируется на accept (2) для одного описания открытого файла.

OTOH, во многих (если не во всех) ядрах проблема с гремящим стадом в паттерне select-accept, как вы описываете, все еще существует.

Я написал простой скрипт (https://gist.github.com/kazuho/10436253) для проверки существования проблемы и обнаружил, что проблема существует в Linux 2.6.32 и Darwin 12.5.0 (OS X 10.8.5).

10 голосов
/ 07 февраля 2010

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

Тем не менее, система select имеет ряд проблем с масштабируемостью просто из-за своего API. Когда у вас большое количество файловых дескрипторов, стоимость вызова select очень высока. Это связано прежде всего с необходимостью создавать, проверять и поддерживать наборы FD, которые передаются в системный вызов и из него.

В наши дни предпочтительным способом асинхронного ввода-вывода является epoll . API гораздо проще и очень хорошо масштабируется для различных типов нагрузки (много соединений, большая пропускная способность и т. Д.)

2 голосов
/ 12 февраля 2015

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

http://lwn.net/Articles/632590/

2 голосов
/ 27 ноября 2012

Недавно я видел протестированный сценарий, когда несколько потоков опрашивали в сокете прослушивающего домена unix и затем принимали соединение. Все потоки проснулись с помощью системного вызова poll ().

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

Мы не пробовали epoll.

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