В чем разница между {активным, ложным}, {активным, истинным} и {активным, один раз}?
Как вы, наверное, знаете, существует три режима gen_tcp. {active, false}
, {active, true}
а также {active, once}
,
Я прочитал несколько документов о {active, false}
, {active, true}
а также {active, once}
, Однако я не получил это.
Какая разница между {active, false}
а также {active, true}
а также {active, once}
?
Не могли бы вы объяснить прямо?
2 ответа
Речь идет об управлении потоком: у вас есть процесс Erlang, обрабатывающий входящий сетевой трафик. Обычно вы хотите, чтобы он быстро реагировал на входящие пакеты, но вы не хотите, чтобы его очередь сообщений росла быстрее, чем он может ее обработать - но в некоторых случаях у вас будут другие цели.
С {active, false}
у вас есть явный контроль, когда процесс получает входящий трафик: это происходит только при вызове gen_tcp:recv
, Однако пока процесс ожидает gen_tcp:recv
, он не может получать другие сообщения Erlang. Возможно, какой-то другой процесс Erlang отправляет сообщение, в котором говорится об остановке, но он пока не знает об этом, потому что концентрируется на получении сетевого ввода.
С {active, true}
сетевой ввод отправляется процессу как сообщение, как только оно становится доступным. Это означает, что вы могли бы иметь receive
выражение, которое ожидает как сетевой трафик, так и простые сообщения Erlang от других процессов. Этот режим работы может быть полезен, если вы уверены, что ваш процесс может обрабатывать ввод быстрее, чем он поступает, но вы можете получить длинную очередь сообщений, которая никогда не очищается.
{active, once}
это компромисс между ними: вы получаете входящие данные в виде сообщений Erlang, это означает, что вы можете смешивать сетевой трафик с другой работой, но после получения пакета вам необходимо явно вызвать inet:setopts
с {active, once}
снова, чтобы получить больше данных, чтобы вы могли решить, насколько быстро ваш процесс получает сообщения.
Поскольку Erlang/OTP 17.0 есть еще один вариант, {active, N}
где N - целое число Это означает, что вы можете получить N
сообщения, прежде чем вам нужно позвонить inet:setopts
снова. Это может дать более высокую пропускную способность без отказа от управления потоком.
{активный, ложный}
Вы должны прочитать часть данных из сокета, вызвав gen_tcp: recv ().
{активный, правда}
Erlang автоматически считывает порции данных из сокета для вас, собирает порции в полное сообщение и помещает сообщение в почтовый ящик процесса. Вы читаете сообщения, используя receive
пункт. Если какой-то враждебный актер заполонит ваш почтовый ящик сообщениями, ваш процесс потерпит крах.
{активный, один раз}
Эквивалентно {active, true}
для первых порций данных, прочитанных из сокета, затем {active, false}
для любых последующих кусков данных.
Вы также должны понимать, как указать {packet, N}
влияет на вещи. Смотрите здесь: Erlang gen_tcp ничего не получает.