LINUX.ORG.RU

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

интересная тема, да.

подпишусь

user_id_68054 ★★★★★
()
Ответ на: комментарий от user_id_68054

каждого по циклу

имелось ввиду «в одном большом цикле» :)

user_id_68054 ★★★★★
()

Вообще-то поллирг и блокирующий ио как раз и придумали для того, что-бы не применять неблокирующий ввод/вывод без поллинга. Твой вопрос эквивалентен вопросу: «Есть ли практическое применение ложки с дыркой?».

nanoolinux ★★★★
()
Ответ на: комментарий от urquan

Не совсем понятно что ты имеешь ввиду. Ну есть у тебя большое количество ио. Засунул всё в селект и джи. Но это же поллинг, не?

nanoolinux ★★★★
()
Ответ на: комментарий от nanoolinux

Что мешало заюзать селект?

много тысяч сокетов — и высокая вероятность что бОльшая часть из них (а может даже все) будет иметь изменённое состояние — уже к концу «большого цикла».

как бы — не было смысла спрашивать об состоянии через select (и передавать в select все эти тысячи объектов).. если можно было просто в очередном «большом цикле» спросить у каждого сокета :-)

user_id_68054 ★★★★★
()
Ответ на: комментарий от nanoolinux

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

Ты когда нибудь использовал poll/epoll на практике?

nerdogeek
() автор топика
Ответ на: комментарий от nerdogeek

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

NegatiV
()
Ответ на: комментарий от nanoolinux

Ну, смысл в том, что он тебе сразу вернёт номер дескриптора в котором событие произошло.

ну вот например у меня 20000 сокетных объектов (в режиме nonblock-io... а программа запущена через ulimit).

я их всех в «большом цикле» попросил что-то сделать.

когда этот цикл закончился — наверняка 19990 из 20000 уже сделали то что их попросили :-) ..

можно к годалке не ходить :) . остальные 10 из 20000 сокетов (которые по какой-то причине не успели сделать то что их попросили) --- проще выявить через проверку их статуса, напрямую спросив у них статус.

user_id_68054 ★★★★★
()
Последнее исправление: user_id_68054 (всего исправлений: 3)
Ответ на: комментарий от nanoolinux

Данные с сокета просто появляются в почтовом ящике потока, и пока ты с помощью receive-выражения не скажешь что они тебе нужны:

receive %% Запроса к сокету здесь нет(!), данные с него либо были, либо нет
    {udp, _Sock, _Addr, _Port, Bin} -> {ok, Bin} 
end.
поток будет работать без поллинга и блокировок дальше. Еще можно проверить есть ли что-нибудь с сокетов без блокировки:
receive %% Запроса к сокету здесь нет(!), данные с него либо были, либо нет
    {udp, _Sock, _Addr, _Port, Bin} -> {ok, Bin} 
after 0 -> {error, no_data}
end.
Разве не об этом речь?

NegatiV
()
Ответ на: комментарий от user_id_68054

Я так понимаю речь о чтении из сокета была, а не о записи. Кроме того, даже если говорить о записи, представь что „наверняка“ не сработало. Тогда ты будешь крутиться в бесполезном цикле получая ewouldblock (или как он там?) при каждой попытке записи.

nanoolinux ★★★★
()
Ответ на: комментарий от NegatiV

Первый вариант это и есть поллинг. Процесс ждёт пока в какой-либо из его сокетов не придут данные. Второй - да, но внимание вопрос: как это сделано внутри вм? Ты же сам вроде писал, что еполл? Я не в курсе если что.

nanoolinux ★★★★
()
Ответ на: комментарий от nanoolinux

Я так понимаю речь о чтении из сокета была, а не о записи. Кроме того, даже если говорить о записи, ...

в моём примере — речь идёт и о записи о чтении из каждого из 20000 сокетов.

просто в своём примере — я делю упор на то что не опрашиваю epoll\poll\select — так как считаю что в моём случае сокетные объекты работают быстрее чем проходит весь «большой цикл» моей НЕмногонитеевой программы.

представь что „наверняка“ не сработало. Тогда ты будешь крутиться в бесполезном цикле получая ewouldblock (или как он там?) при каждой попытке записи.

ну разумеется несколько сокетов из 20000 — не успеют сделать что-то .. или не получат данных (в момент когда их спросят о состоянии).

но я расчитываю на то что это будет меньшенство сокетов.

а в случае если вдруг интернет-канал станет неожиданно медленным (или вовсе разовался) — то моя программа начнёт действительно производить бесполезную работу по нагреванию помещения процессором :-) ....и в вот в этом случае epoll\poll\select смог бы исправить такую неожиданность. :)

user_id_68054 ★★★★★
()
Последнее исправление: user_id_68054 (всего исправлений: 3)
Ответ на: комментарий от nanoolinux

Тут нужно понимать что поток ждет данные из ящика, а не сокета. А то как это сделано внутри ВМ разве имеет значение? Главное как это выглядит с прикладной части, а для потока Erlang это выглядит как nb i/o без поллинга.

NegatiV
()
Ответ на: комментарий от NegatiV

Хорошо, я согласен. Но только во-первых: не поток, а процесс, во-вторых: всё таки ты всего лишь нарисовал возможность это сделать в эрланге. Но для чего это делать? Я например даже не представляю нахрен делать

receive
  {udp, _, _, _, Data} -> some_function(Data)
after 0 -> no_data
end
Где это может пригодиться? Кроме как для выкидывания хлама в виде юдипишных сообщений из мбокса (что вообще говоря достигается exit(restart_me_please)) нигде не применить.

nanoolinux ★★★★
()
Последнее исправление: nanoolinux (всего исправлений: 1)
Ответ на: комментарий от nanoolinux
receive
    {udp, RTCPSock, _Addr, _Port, Data} -> parse_rtcp( ... )
after 0 ->
end,

receive
    {udp, RTPSock, _Addr, _Port, Data} -> parse_rtp( ... )
after ?MAX_RTP_DELAY -> {error, timeout}
end,

....

Может пригодится в случаях извлечения данных из ящика с приоритетом.

NegatiV
()
Ответ на: комментарий от nanoolinux

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

nerdogeek
() автор топика
Ответ на: комментарий от nanoolinux

Надо смотреть как в nginx сделано.

в nginx меньше сокетов чем 20000.

там по умолчанию максимум лимит: 100 или 1000 , непомню точно сколько.. (этот лимит хотя можно увеличить в конфиге, но при этом нужно и не забыть повысить системные лимиты для nginx на количество файловых дескрипторов).

и думаю в один момент времени — в nginx врядли будет более 300 сокетов — на практике.

300 это явно меньше чем 20000 :-) ..

Если даже там через селект - то твоя идея... ну ты понял)

ну я и так знаю что моя описнная реализация — лишь говно-хак :) ...

...но просто я упомянул в этой теме что мол "да, есть такие люди которые сделали программу с non-block сокетами и при этом без select\poll\epoll .. и эти люди — я"

user_id_68054 ★★★★★
()
Ответ на: комментарий от nerdogeek

Тебе привет от man epoll

An application that employs the EPOLLET flag should use nonblocking file descriptors to avoid having a blocking read or write starve a task that is handling multiple file descriptors.

nanoolinux ★★★★
()
Ответ на: комментарий от nanoolinux

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

NegatiV
()
Ответ на: комментарий от user_id_68054

в nginx врядли будет более 300 сокетов

Серьёзно? Всего 300?! Я раньше думал, что это такой мегакомбайн для http, а оно только 300 сокетов удерживает? Можно ссылку на данные или пруф?

cast vromanov

nanoolinux ★★★★
()
Ответ на: комментарий от NegatiV

Можно ещё и по айпишнегам фильтровать) Эрланг - вещь!)

nanoolinux ★★★★
()
Ответ на: комментарий от nanoolinux

Я раньше думал, что это такой мегакомбайн для http, а оно только 300 сокетов удерживает?

яж говорю сколько он обрабатывает на практике — у web-хостеров. :)

а удерживать он способен и больше.

но опять же вопрос — что считать «удерживает».

тормозить-то он будет тем больше чем больше пользователей.

а мощное серверное железо которое обрабатывает большое число одновременных пользователей — оно зачастую настолько мощное что способно обрабатывать их при любой реализации софта :)

user_id_68054 ★★★★★
()
Последнее исправление: user_id_68054 (всего исправлений: 2)
Ответ на: комментарий от user_id_68054

в nginx меньше сокетов чем 20000

nginx умеет epoll. Хоть 1 миллион.

и думаю в один момент времени — в nginx врядли будет более 300 сокетов — на практике

Нас недавно досили ~100 000 ботов. Соединяются по HTTP / SMTP и шлют сколько могут, или открывают соединение и вяло в него побайтно пишут. 30 000 - 50 000 открытых соединений одновременно на ровном месте.

sf ★★★
()
Ответ на: комментарий от sf

nginx умеет epoll. Хоть 1 миллион.

epoll это вообще класно, кстати.

я разумеется думаю что epoll нужен

user_id_68054 ★★★★★
()
Последнее исправление: user_id_68054 (всего исправлений: 1)
Ответ на: комментарий от sf

30 000 - 50 000 открытых соединений одновременно на ровном месте.

на умышленный DoS похоже.. мне кажется :)

ааа.. ну ты так и написал:

Нас недавно досили ~100 000 ботов.

а рабочих (не ботов) сколько соединений?

но всё равно это похвально что nginx справляет!

user_id_68054 ★★★★★
()
Последнее исправление: user_id_68054 (всего исправлений: 2)
Ответ на: комментарий от sf

ясно.. ну вот я это и мею ввиду, говоря про 300 :)

а боты — они «тянули резину» с соединением — до самого конца?

в смысле доходил ли запрос бота — до своего конца запроса (до конца HTTP-шапки), или запрос был медленным и с «бесконечным» числом заголовков HTTP-шапки?

(так-то я знаю что у nginx (как и у любого другого нормального HTTP-сервера) есть лимит на количество байтов для шапки HTTP-запроса --- но мне интересно учли ли это создатели ботов).

user_id_68054 ★★★★★
()
Ответ на: комментарий от user_id_68054

ясно.. ну вот я это и мею ввиду, говоря про 300 :)

Этот сервер совсем маленький - 400 MB RAM, 1 CPU.

На свете бывает больше 300 соединений. Типичный случай - анонс релиза $whatever на slashdot и LOR.

а боты — они «тянули резину» с соединением — до самого конца?

Были такие:

- большие и глупые (развод на трафик): шлют хедеры с большим числом пробелов (nginx их рубил по размеру)

- маленькие и гадкие (задосить backend): много маленьких POST-ов на страницы с формами (добавил рубку прямо в конфиг nginx по специфичным заголовкам)

- маленькие и медленные (сожрать ресурсы frontend): побайтная передача с большими интервалами (nginx их рубил по таймауту)

Довольно тупые, ниже уровня TCP никаких шуток. Но много :]

sf ★★★
()

У нас на libev сделана сетевая часть. Соединений не много, но может быть относительно большой поток сообщений до 200000 в секунду. Все очень просто и асинхронно.

vromanov ★★★
()

есть, обычно цикл оборачивают в reactor pattern.

dizza ★★★★★
()

Есть ли практическое применение non-blocking i/o без поллинга?

Пользовал, прада было не тысячи сокетов, а всего один. Опрос сокета в гуевой программулине по таймеру. Потоки городить было лень, а вызывать select, чтобы потом вызвать еще recv... Проще сразу recv и проверку на EWOULDBLOCK. Задержки в 100 мс хватило всем.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.