LINUX.ORG.RU

Царю про 10к в надежде перевести дискуссию в конструктив

 ,


11

10

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

Если ты готов померять реальный перформанс, пиши, я налабаю на еполле аналоги твоих тестовых серверов, чтобы не ты один тратил своё время. Меня например больше в всего в контексте этого спора интересует, как поведёт себя сервер с 10к потоков например на 4 ядрах против еполльного на одном таком же ядре, в вариантах без локов и с.

Результаты исследования можешь запостить на ЛОРе и восстановить честь среди пятизвездочных 😝

Начало дискуссии где-то рядом в удаленных по инициативе какого-то наркомана.

PS скорее всего я отвечу не раньше ночи или следующего утра.

★★★★★
Ответ на: комментарий от eao197

Любая простыня текста без конкретного ответа означает, что ты не обеспечиваешь корректность _твоего_ кода.

Твои потуги ничего не значат. И из них ничего не следует. Ты попытался играться со мною - потерпел неудачу. Это предсказуемо. Мы родились в разных весовых категориях - да, мир несправедлив. Я в тебе 5минут, ты в ней 10лет. Ты уже мне проиграл. Так бывает.

Параллельных активных — это значит параллельных (существующих в одно время) и активных (это значит, что работа идет одновременно по всем, нет такого, что активна 1/10 часть коннектов, а 9/10 чего-то ждут).

Эти глупые формулировки. Активных это что? Поподробнее. Какой критерий определяющий «активность» коннекта? Существовать в одно время должно что?

Я тебе сказал. Я понял к чему ты юлишь. Ты к этому не выюлись. С соседями по парте прокатит - со мной - нет. Уже давно пора понять.

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

Я в тебе 5минут, ты в ней 10лет.

Я в теме 5 минут - ты в ней 10 лет.

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

Смешно. Верю. Царь мне не дал поиграть в мои детские игрульки - какой царь подлец. Обижусь на него.

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

Смысл споров - это добиться правды, разобраться, узнать новое, показать людям новое. Ты же пытаешься найти оправдания тому, что ты там можешь меня выиграть. Что полезного это даёт? Ты в этом сам веришь? Публика в этом верит? Глупая затея. Тем, кто в твоём положении итак будут считать и говорить везде то же, что и ты. Другие в такое не поверят. Ну разве что совсем мимокрокодилы.

Да, я может быть был не прав, когда тебя обижал. Я сам помешал тебе воспринимать информацию вменяемо - ты теперь просто агришься на меня.

Но я сомневаюсь, что было бы иначе, если бы я этого не делал. Мои изначальные спорты с тобою были идентичны - я тебе ничего не делал. Ты пытался играть в то же самое. Поэтому я не особо себя виню в том, что произошло с тобою.

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

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

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

А то «все кто несогласен - идиоты» - это такое себе. При ладно бы ты обосновать что-то мог, либо твоё мнение было бы верным и хоть что-то из себя представляло, но нет же.

Вам не нравится как я себя веду, но дак я ведь ваша копия. 1в1. Просто ты говоришь популярное, а я нет.

Я хочу вменяемости. Можешь ли ты в неё?

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

Я хочу вменяемости.

Начни с того, чтобы односложно ответить на прямой простой вопрос.

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

Основания для подобного балабольства в студию.

начнем с того, что говнокод твоего сервера https://pastebin.com/RVHfBkuc вообще не компилируется: http://ideone.com/iPNUCq

вот когда доведешь его до компиляции, ТОГДА можно будет перейти ко второй части марлезонского балета — тесту, в котором write в твоем коде вернет меньше 1024 без сигнала

я, естественно, довел твой говнокод до компиляции и немного отрефакторил — но ты должен САМ предъявить компилируемый код, а то, если я сам выкачу исправленную версию твоего говнокода, в лучших царских традициях будешь утверждать, что я его испортил

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

О боже, какая глупая балаболка. Выкинь свой компилятор с помойки. https://godbolt.org/g/VVQnGb

я, естественно, довел твой говнокод до компиляции и немного отрефакторил — но ты должен САМ предъявить компилируемый код, а то, если я сам выкачу исправленную версию твоего говнокода, в лучших царских традициях будешь утверждать, что я его испортил

Что ты несёшь? Чего исправил? Естественно ты его не пастишь сюда, ибо ты балабол и ссышься показать своё дерьмо.

А самое интересное, что балаболы балаболят про мой код, про то какое он дерьмо, что у меня его нет. При этом его даже не смотрели. Обожаю.

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

О боже, с кем я связался.

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

спасибо, разговор может стать предметным

На счет предметного разговора. Посмотрел немного на код клиента из бенчмарка Царя.

Там, действительно, создается 10k параллельных коннекта. Т.е. на стороне сервера все рабочие нити должны успешно выйти из вызова accept и повиснуть на read-е в ожидании 8 входящих байт из клиента.

Однако, основная работа клиента выполняется довольно хитрым способом.

Во-первых, вся работа ведется всего с одного рабочего потока. Т.е. клиент в один момент времени может читать или писать всего в один сокет.

Во-вторых, когда клиент подключается к серверу, то все сокеты сохраняются в epoll_fd (см. вызов client::add_to_poll из client::connect). Однако, при обращении к epoll_wait количество epoll_event-ов ограничивается всего 1024 штуками (см. определение константы epoll_event_size и статического массива edata внутри client). Это означает, что клиент последовательно(!) будет обрабатывать не более 1024 готовых сокетов. Из 10k.

Как я предполагаю, получается следующее:

Клиент устанавливает 10k коннектов к серверу. Сервер за это время практически для всех коннектов сделает accept и практически для всех коннектов сделает вызов read.

Затем клиент начинает дергать epoll_wait с ограничением на 1024 сокета. Практически сразу система должна отдать клиенту 1024 сокета, которые готовы для записи (они ведь готовы). Клиент в один поток, последовательно, выполняет запись 8 байт в каждый из сокетов.

А вот дальше могут быть варианты. Если на loopback-интерфейсе не действует алгоритм Нейгла, то запросто может произойти так, что когда клиент еще находится внутри write(..., 8), сервер уже может сделать read(..., 8). И, более того, сервер уже может успеть записать ответные 10KiB данных. Это означает, что когда клиент сделает второй epoll_wait, то те же самые сокеты, которые только что были готовы для записи, уже окажутся готовы для чтения, и клиент тут же начнет читать ответные данные (не более чем по 1KiB за раз).

Но даже если алгоритм Нейгла действует на loopback-е, то это позволит клиенту сделать write(...,8) для большинства сокетов прежде, чем данные начнут доходить до сервера. Зато потом, когда сервер начнет отвечать, клиенту уже не придется дергать write(..., 8), он все время будет тратить на read(..., 1024).

Как бы то ни было, фокус в том, что клиент работает в один поток и в один момент времени выполняет read/write всего над одним сокетом. При этом окно рабочих сокетов ограничивается ~1/10 от их общего количества.

Получается, что клиент создает 10k параллельных соединений, но активно (т.е. выполняется либо read, либо write) всего одно соединение.

Там есть еще прикольный момент с проверкой корректности идущих от сервера данных, но это уже совсем мелочи.

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

https://godbolt.org/g/VVQnGb

царь таки раздуплился ссылкой на свой код...

Выкинь свой компилятор с помойки.

не-не, спасибо, я подожду, когда этот компилятор как следует оттестят, тогда, может, и возьму

Чего исправил?

удалил ненужное использование с++17, лишнее сложение строк, лишнюю лямбду, лишний класс

добавил печать диагностики в случае успеха, а не только облома

Естественно ты его не пастишь сюда

да без проблем, могу запостить исправленную версию твоего говнокода — она хоть и стала поприличнее, но работать будет как и твой — неверно

но меня больше интересовали фактические ошибки, поэтому я займусь твоим кодом под твоим компилятором

При этом его даже не смотрели.

да-да-да, вот так спал и не глядя в твой код его рефакторил

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

Это означает, что клиент последовательно(!) будет обрабатывать не более 1024 готовых сокетов. Из 10k.

Что ты несёшь, пощади меня. Не буду комментировать этот - я уже устал.

А вот ответь мне, пж. А ты не мог взять, поменять эту константу и измерить разницу? Или ты только балаболить можешь?

//1024
rq = 100000

real    0m0,302s
user    0m0,010s
sys     0m0,225s


//10240
rq = 100000

real    0m0,301s
user    0m0,000s
sys     0m0,248s


И всё балабольство разбивается в прах. Ну ничего - бывает.

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

Как бы то ни было, фокус в том, что клиент работает в один поток

само собой, тестить его сервер надо своим клиентом

че-нить командно-строчное подскажешь? чтобы оно эмулировало непроходимосить сети или хотя бы тормознутый клиент?

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

А ты не мог взять, поменять эту константу и измерить разницу?

Так у тебя же вся нагрузка генерируется в один поток и читается/пишется не более одного сокета за раз. С чего бы разница взялась, если для epoll_wait на современной машине, что 1024 сокета вернуть, что 10240, разницы не составляет.

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

Так у тебя же вся нагрузка генерируется в один поток и читается/пишется не более одного сокета за раз.

Как и везде.

С чего бы разница взялась, если для epoll_wait на современной машине, что 1024 сокета вернуть, что 10240, разницы не составляет.

Если нет разницы - зачем ты о ней кукарекал? Зачем ты пытаешься юлить.

Во-вторых, когда клиент подключается к серверу, то все сокеты сохраняются в epoll_fd (см. вызов client::add_to_poll из client::connect). Однако, при обращении к epoll_wait количество epoll_event-ов ограничивается всего 1024 штуками (см. определение константы epoll_event_size и статического массива edata внутри client). Это означает, что клиент последовательно(!) будет обрабатывать не более 1024 готовых сокетов. Из 10k.

Затем клиент начинает дергать epoll_wait с ограничением на 1024 сокета. Практически сразу система должна отдать клиенту 1024 сокета, которые готовы для записи (они ведь готовы). Клиент в один поток, последовательно, выполняет запись 8 байт в каждый из сокетов.

Это, это ты просто так написал? Ты действительно веришь, что такой ответ прокатит?

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

Не, не подскажу, я ж не настоящий сварщик :(

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

Как и везде.

Да ты совсем дебил.

Это, это ты просто так написал?

Это я написал, как твой клиент работает. Констатация фактов это называется.

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

Так у тебя же вся нагрузка генерируется в один поток и читается/пишется не более одного сокета за раз.

кстати, вот как это можно доказать: поставить на сервере мьютекс (или семафор), который не позволяет работать более чем 1 (или N) нитей за раз

я бы взялся, но у меня пока что жцц 7-го нет, а без него царь может начать выпендриваться

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

само собой, тестить его сервер надо своим клиентом

Да, еще про одну штуку забыл написать. Обычно, когда делают нагрузку на сервер с ограничением на N параллельных запросов, то выдают не строго N запросов, а N*K, где K может быть и 10, и 100, и 1000, и больше.

Т.е. чтобы показать поведение сервера в режиме c10k нужно не 10k запросов, а хотя бы 100k запросов (с окном в 10k активных).

Тут же всего 10k и все. Поэтому можно на сервере писать sleep(10) в рабочих нитях и «это ни на что не влияет» (с) ;)))

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

sleep(10) в рабочих нитях

не знаю как других, но меня постоянно в этом треде дикий ржач пробивает

вот и сейчас... по поводу sleep(10) в рабочих нитях...

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

Ну как, написали пару клиентов? Или это 15 страниц постановки тех.задания?

вот сервер царя https://godbolt.org/g/VVQnGb

вот еполл-сервер https://pastebin.com/AMD6LQrw

техзадание с участием царя ставить бесполезно, так как он обязательно потом скажет что в реальности таких задач не бывает и вообще «невозможно рассчитать физическое воздействие, насколько будут отличаться свойство реального и расчётного объекта»

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

мимокрокодильный аноним

ИМХО, обе портянки кода выглядят как говно. Пофик что работают, но код выглядит адово.

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

еще через 15 страниц дойдут до бенчмарков ))))

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

Обоснования в студию

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

1) для такой задачи плюсы не нужны 2) процедура work написана в стиле (once write, never read). Я бы декомпозировал дабы сделать код хоть немного более читабельным 3)

  sockaddr_in saddr{};
  saddr.sin_family = AF_INET;
  saddr.sin_port = htons(port);
  saddr.sin_addr.s_addr = htonl(addr);
  int listen_fd = safe_call(socket(AF_INET, SOCK_STREAM, 0));
Что за привычка старых пердунов писать в стиле C89? Господь Б-г тебе дал designated initializer, но ах и ох, ты не можешь их юзать, ибо грёбаные плюсы. Читаешь потом такие портянки с структурами и офигеваешь с людей. 4) танцы с safe_call внутри воркера вообще умиляют 5) про read() из сети и проверку возвращаемого значения тебе уже ЕМНИП говорили

anonymous
()
Ответ на: комментарий от i-rinat

Царь.

Кстати, кстати, балаболка? Как там с теорией заговара? Уже призвал своих подельников и подчистил?

Ой, обожаю вас. Так пыжился, но через час-два бах, и все ветки с ним пропали. Как так получилось?

А вот это: можно ли *временно* закрыть тему с царем для анонимусов? что? Не попытка заткнуть меня?

Кстати, дак его подельник ещё и забанил меня. Совсем пацаны не палятся.

А вы смотрите, как трясётся за свои звезздульки вся эта пятизвёдочная братия. Как же они хотят тереть, в крысу банить, что потом всем петь «как же царь слился и как он не пишет».

Кстати, эта же балаболка в теме лорконтеста сделала то же самое. Сменила условия, начал тереть, а после забанила и начала болтать «а царь слился - не отвечает». Крысятские повыдки не меняются.

Убожество.

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

1) для такой задачи плюсы не нужны

Меня твоё мнение не волнует.

2) процедура work написана в стиле (once write, never read).

То же самое.

Я бы декомпозировал дабы сделать код хоть немного более читабельным

Вперёд. Выкатывай.

Что за привычка старых пердунов писать в стиле C89?

О боже, убогий ламерок, не тебе меня учить как писать.

Господь Б-г тебе дал designated initializer, но ах и ох, ты не можешь их юзать, ибо грёбаные плюсы.

Как там, вчера узнал? Ну ничего.

танцы с safe_call внутри воркера вообще умиляют

Поподробнее.

5) про read() из сети и проверку возвращаемого значения тебе уже ЕМНИП говорили

Поподробнее. Где что и как это должно быть и почему.

Пока что ничего. Ты кукарекал за говнокод, а выклал только «кукареку кресты ненужны» и своё, мне абсолютно не интересное псевдомнение из которого ничего не следует.

Разделил - покажи как. Не смогу? Не воняй. Что-то нетак? Показывай что. Балабольство уровня «не так потому что я так сказал» не работает. Им ты можешь только подтерерться.

anonymous
()
Ответ на: мимокрокодильный аноним от anonymous

ИМХО, обе портянки кода выглядят как говно. Пофик что работают, но код выглядит адово.

первая портянка не только выглядит как говно, но и пахнет как говно, и... ну ты понял, надеюсь

вторую я внимательно не читал, написана она поаккуратнее первой, но страдает от отсутствия с++ — скажем, все эти постоянные проверки на == -1 надо чем-то обернуть

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

опа, вот тут ты и попался на демагогии )

только зря ты палку немного перегнул - сам в ней утонешь 1)

Меня твоё мнение не волнует.

Хотя перед этим ты сказал

Обоснования в студию

/0

Идём далее

То же самое.

Ну так то же самое же!

Вперёд. Выкатывай.

Мне это не нужно. Ты меня спросил что не так - я ответил. Я где-то вызывался писать код?

О боже, убогий ламерок, не тебе меня учить как писать.

Тебя кто-то учил как писать?

Как там, вчера узнал?

что узнал?

Ну ничего.

что ничего?

Поподробнее.

Ты на -1 на системный вызов внутри цикла, где, собственно, происходит передача данных, реагируешь... тупым выходом из программы? Серьезно? Упоролся штоле, наркоман?

Поподробнее. Где что и как это должно быть и почему.

Тебе read() из сети может вернуть: 1) -1 2) меньше чем просил 3) 0 Во всех трёх сценариях нужно обрабатывать это по-разному. Ты тупо забил на всё.

Пока что ничего. Ты кукарекал за говнокод, а выклал только «кукареку кресты ненужны» и своё, мне абсолютно не интересное псевдомнение из которого ничего не следует.

Ты походу нихрена не понял. Тут НИКОГО НИЧЬЁ МНЕНИЕ НЕ ВОЛНУЕТ. Ни твоё и моё. В этот тред могут писать все. Я могу писать и ты тоже. И то, что у тебя рвёт пукан от каждого поста в этом треде сугубо твои проблемы. Я тебе ответил - дальше твои проблемы.

Не воняй.

Буду. Я же могу - буду вонять столько сколько посчитаю нужным.

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

Что за привычка старых пердунов писать в стиле C89? Господь Б-г тебе дал designated initializer, но ах и ох, ты не можешь их юзать, ибо грёбаные плюсы

кстати да; щас попробую еще и это переписать на плюсах покрасивее, не знаю, выйдет ли

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

только зря ты палку немного перегнул - сам в ней утонешь 1)

В параллельной вселенной.

Хотя перед этим ты сказал

Обоснование должно быть конкретным. Балабольство на тему «это говно, потому что я так сказал» не являются обоснованием. А являются его отсутствием.

Мне это не нужно. Ты меня спросил что не так - я ответил. Я где-то вызывался писать код?

Да, ты начал балаболить, что как-то бы сделал иначе. Есть два варианта - ты балабол и второй - ты не балабол. Балаболом ты является по умолчанию, пока не докажешь обратное. Ты не доказал, а значит вариант остался один. Трепло.

Тебя кто-то учил как писать?

Дело в том, что потуги всяких рандомных ламерков в мою сторону - это просто смешно. Да и это не важно, ведь из твоего балабольства всё равно ничего не следует.

Ты на -1 на системный вызов внутри цикла, где, собственно, происходит передача данных, реагируешь... тупым выходом из программы? Серьезно? Упоролся штоле, наркоман?

Очередной слив засчитан. Да, если нарушен инвариант - результаты измерений невалиден и продолжать их не имеет смысла.

А то, что обгадившиеся балаболки пытаются как-то всплыть и нести херню - дак из этого, повторюсь уже в 10 раз, ничего не следует. Ни к какой «программе» этот код отношения не имеет. Никакие условия обгадившихся балаболов исполнять не должен.

Тебе read() из сети может вернуть: 1) -1 2) меньше чем просил 3) 0 Во всех трёх сценариях нужно обрабатывать это по-разному. Ты тупо забил на всё.

Не нужно. Задача кода продемонстрировать работоспособность концепции. Никакой твоей шизофрении он следовать не должен. Если ты, балаболка, хочешь найти место, что у меня может что-то нарушится - ты это находишь. Не можешь. Не кукарекаешь.

Ты походу нихрена не понял. Тут НИКОГО НИЧЬЁ МНЕНИЕ НЕ ВОЛНУЕТ. Ни твоё и моё. В этот тред могут писать все. Я могу писать и ты тоже. И то, что у тебя рвёт пукан от каждого поста в этом треде сугубо твои проблемы. Я тебе ответил - дальше твои проблемы.

Естественно, мнение рандомного балабола никого не волнует. Но - это и не важно. Важно лишь определить то - чего стоит твоё мнение. Стоит оно ноль.

Причина проста - ты не можешь обосновывать своё мнение своим мнением. Если у тебя нет оснований - ты трепло. А какое там у тебя мнение и чьё это мнение - естественно, меня не волнует.

Буду. Я же могу - буду вонять столько сколько посчитаю нужным.

Можешь. Но я хочу определить. Чего стоит твоя вонь. Имеет твоё мнение основание, либо ты просто пришёл покукарекать.

Пока я эти оснований не вижу, но ты можешь пытаться дальше.

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

кстати да; щас попробую еще и это переписать на плюсах покрасивее, не знаю, выйдет ли

В крестах нельзя это «покрасивее» переписать и тебе об этом сказали. Опять же - ты бы хоть погуглить о чём вообще речь. Ну это такое.

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

вторую я внимательно не читал, написана она поаккуратнее первой, но страдает от отсутствия с++ — скажем, все эти постоянные проверки на == -1 надо чем-то обернуть

Ну, скажем так, не то чтобы поаккуратнее... Просто другой стиль, и человек имеет какой-то опыт, хоть и профдеформированный. Давай откусим хотя-бы верхний кусочек:

static void * xmalloc(size_t nelems, size_t elemsz)
{
    size_t n = nelems * elemsz;
    void *r = malloc(n);
    if (!r && n) {
        fprintf(stderr, "Out of memory.\n");
        abort();
    }
    return r;
Танцы с xmalloc я вообще не понял.

Зачем два аргумента? Чтобы в месте, где вызывают не использовать оператор умножения? А потом внутри функции проверять не ввёл ли кто-то 0? о_О

Именование переменных и проверка значений явно родом с девяностых.

static void *xmalloc(size_t msize1, size_t msize1)
{
    void *mem = malloc(msize1 * msize2);
    if (mem == NULL) {
        perror("Out of memory");
        abort();
    }
    return mem;
}

}
дальше
static int make_nonblock(int fd)
{
    int flags = fcntl(fd, F_GETFL); // хз почему может быть < 0. EBADF? Ну тогда и вызов fcntl() ниже вернёт -1 вместе с EBADF
    if (flags < 0 || fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { // можно объединить в 1 выражение
        return -1; // -1 и 0 возвращают сами fcntl(), нет смысла их возвращать самостоятельно
    }
    return 0;
}
static inline int make_nonblock(int fd)
{
    return fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK) < 0);
}
а вот это вообще жестяк:
enum { BUFSZ = 4 * 1024 };
...
#define datum_fd(Dtm_)  (Dtm_)->fd
там половина портянки выглядит как ptrtostruct->field, в чём прикол этого макроса? в чём скаральный смысл таких анонимных енумов, если есть нормальный дефайн? 4 * 1024 это что вообще? я бы вынес константы, которые имеют логический смысл в начало файла и нормально бы их именовал, чтобы не читать вот эту жесть с

1024

Дальше код читал по диагонали. Выглядит слегка «лапшично». Ну и блин. Опять наследие сишников старых пердунов:

return 1;
вместо
return EXIT_FAILURE;
Но вообще автор понимает что он делает, ему бы хорошенький рефактор не помешал бы.

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

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

Задача кода продемонстрировать работоспособность концепции

А я говорил где-то что крайне важно для концепции (или демонстрации) красота и стиль кода? Я ДВАЖДЫ тебе сказал, что это не важно, что главнА работоспособность но ты продолжаешь строить из себя демагога. Я же говорил что ты утопишь себя в своей же демагогии. Вот ты и слился. Попробуй в след. раз НОВОГО собеседника воспринимать с дефолтным значением (т.е. не воспринимать его как говно), а не так, как ты воспринимаешь очередного лоровского регистранта.

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

В крестах нельзя это «покрасивее» переписать

Зачем тогда вообще писать на крестах?

тебе об этом сказали

ты меня с кем-то путаешь. Мне ничего не говорили, а то, что читание крестов ничем не лучше читания индусского похапе кода я и сам знаю.

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

А я говорил где-то что крайне важно для концепции (или демонстрации) красота и стиль кода?

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

Т.е. тем самым ты на основании отсутствия НЕНУЖНОСТИ с моём коде сделал вывод, что он говно. Да ты гений, слушай.

ДВАЖДЫ тебе сказал, что это не важно, что главнА работоспособность но ты продолжаешь строить из себя демагога.

Меня не волнует что ты сказал и какая-то работоспособность. При этом ты и начал балаболить про рабоспособность, а именно «выпадает на ошибке», либо «не проверяет результат» - это именно, что работоспособность.

Я же говорил что ты утопишь себя в своей же демагогии.

О боже, чтобы я утонул - нужно 20 подобных тебе спаять в одного и только потом, и то возможно, из этого выйдет какой-то толк.

Вот ты и слился.

Основание.

Попробуй в след. раз НОВОГО собеседника воспринимать с дефолтным значением (т.е. не воспринимать его как говно), а не так, как ты воспринимаешь очередного лоровского регистранта.

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

А так ты пришёл, набросил и не смог даже ответить. Ты как минимум не имеешь смысла, а как максимум сводишь тему в дерьмо своим набросом.

Я не против вашего наброса, но придумай что-то получше убого бреда, который я слышу от рандомного регистранта. Тогда - ты им не будешь.

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

а эксепшены из __cyg_profile_func_enter разве можно кидать? (я правда не знаю, но судя по слову «профайл» функция для другого придумывалась)

Фиг знает :( Но gcc-шные исключения умеют проходить сквозь чисто сишные функции, так что, скорее всего, можно.

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

Зачем тогда вообще писать на крестах?

Ты там вообще вменяем? Я тебе что ли это писал? Я писал это регистранту. С какого бадуна ты решил, что писал я в ответ на сообщения регистранта тебе, а не ему?

ты меня с кем-то путаешь. Мне ничего не говорили, а то, что читание крестов ничем не лучше читания индусского похапе кода я и сам знаю.

О боже.

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

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

но вроде ведь щас че-то делают на эту тему? типа c# async?

Бесстековые async/await очень тяжело использовать, так как они требуют пометки всех использующих функций как async/await, бесконечно распространяясь по коду. Если я правильно помню, именно поэтому их так не спешат принимать в стандарт.

А с отдельными стеками уже есть, как раз зелёные нити. Но тут возникают все те же проблемы со стеками, которые мы обсуждаем.

первый раз такое вижу... а так разве можно? (я бы в асме вычел stack_end - rsp и вернул значение в переменной)

В gcc как будто бы можно.

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

Ты там вообще вменяем? Я тебе что ли это писал? Я писал это регистранту. С какого бадуна ты решил, что писал я в ответ на сообщения регистранта тебе, а не ему?

сорян, попутал. Увидел «Re: мимокрокодильный аноним» и подумал что ответ мне, о_О. С этими анонимами уже в глазах рябит...

anonymous
()
Ответ на: В порядке наброса от derlafff

Пока C-крестьяне бунтуются и пишут витиеватую говнолапшу с select, GO-бояре просто создают 10к ко-рутин и спокойно наблюдают, как планировщик использует тот же select, но под капотом, и запускает только те рутины, которым есть, что обработать.

Наброс не защитан: и под си, и под си++ есть библиотеки для оного.

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

Вот видишь как просто, когда у тебя реально есть что сказать. И что произошло в ситуации со мною. Разницу чувствуешь? То-то и оно.

Поэтому не надо так. Хорошо?

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

А по поводу анонимом - ну что поделать. Мне учётку заводить не дают, да и из под анонимама забанить пытаются. Моя учётка живёт до тех пор, пока очередной пятизвёздочный не окажется в зоне риска. Приходится страдать.

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

В крестах нельзя это «покрасивее» переписать и тебе об этом сказали. Опять же - ты бы хоть погуглить о чём вообще речь. Ну это такое.

гыгыгы

анонимус думает, что я не знаю, что такое designated initializer

далее, в принципе можно, но в случае *именно* что sockaddr_in я не уверен

короче смотри код и обрати внимание на то, что:

1. перед sin_family и товарищи старпёрского префикса нет — т.е. все точно как в designated initializer-ах (хотя и это в общем-то похрен, поскольку в хедере)

2. вообще все до /// end of unix_syscall.hpp можно пропустить, т.к. это тонкая обертка, а настоящий код внизу и легко читабелен для сишника

3. царские ошибки я НЕ исправляю, просто переписываю покрасивше с сохранением семантики

4. можно еще покрасивее написать, но надо уж что-то выкатить

#include <sys/mman.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <unistd.h>
#include <sched.h>
#include <stdexcept>
#include <string.h>
#include <thread>
#include <arpa/inet.h>
#include <sys/fcntl.h>

bool logging = true;

/// start of unix_syscall.hpp --- тонкая обертка над сисколлами и структурами ядра

struct SockAddrInet: public sockaddr_in /// за правильность этой структуры я не ручаюсь
{
    SockAddrInet( in_addr_t address, uint16_t port )
    {
        sin_family      = AF_INET;
        sin_port        = htons(port);
        sin_addr.s_addr = htonl(address);
    }
};

int safe_call(int value, int line, const char* ctx)
{
    std::string message = std::to_string(line) + " " + std::string(ctx)  +  " == " + std::to_string(value);

    if(value == -1) {
        message += ", errno(" + std::to_string(errno) + ") == " + strerror(errno) ;
        throw std::runtime_error(message);
    }else{
        if( logging )
            fprintf(stderr, "safe_call success: %s\n", message.c_str());
    }
    return value;
}

#define verbose_safe_call(call) safe_call(call, __LINE__, #call)

#define accept(a,b,c)         verbose_safe_call(accept(a,b,c))
#define bind(a,b,c)           verbose_safe_call(bind(a,b,c))
#define listen(a,b)           verbose_safe_call(listen(a,b))
#define read(a,b,c)           verbose_safe_call(read(a,b,c))
#define socket(a,b,c)         verbose_safe_call(socket(a,b,c))
#define setsockopt(a,b,c,d,e) verbose_safe_call(setsockopt(a,b,c,d,e))
#define write(a,b,c)          verbose_safe_call(write(a,b,c))

/// end of unix_syscall.hpp

void worker(int listen_fd, int id)
{
    fprintf( stderr, "start thread(%lu)\n", id );

    while( int accept_fd = accept(listen_fd, nullptr, nullptr) )
    {
        uint64_t buffer[(1024 * 10) / sizeof(uint64_t)];
        read(accept_fd, buffer, sizeof(uint64_t));
        for(auto & x : buffer) x = buffer[0];

        for( auto ptr = std::begin(buffer); ptr < std::end(buffer); ptr += 1024/sizeof(uint64_t) )
        {
            write(accept_fd, ptr, 1024); /// это говнокод, но я тут сохраняю ошибки царя
        }
        close(accept_fd);
        sleep(10); /// и это тоже говнокод, но я тут тоже сохраняю ошибки царя
    }
}

int listen_to(in_addr_t addr, uint16_t port)
{
    const size_t n = 100;
    auto saddr     = SockAddrInet(addr, port);
    auto listen_fd = socket( AF_INET, SOCK_STREAM, 0 );
    int  option    = 1;
    setsockopt( listen_fd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option) );
    bind( listen_fd, (__CONST_SOCKADDR_ARG)&saddr, sizeof(saddr) );
    listen( listen_fd, n );
    return listen_fd;
}

int main()
{
    int listen_fd = listen_to(INADDR_LOOPBACK, 8883);
    const int n=10;

    worker( listen_fd, 0 ); return 0; /// строка для однопоточного теста; для тредов -- закомментить

    std::thread threads[n];

    for(int id=0; id<n; ++id )
    {
        threads[id] = std::thread( worker, listen_fd, id );
    }

    return 0;
}

да, как это тестить:

user@host $ nc 127.0.0.1 8883
abcd<этнер>

выхлоп сервера:

safe_call success: 77 socket(2,SOCK_STREAM,0) == 3
safe_call success: 79 setsockopt(listen_fd,1,2,&option,sizeof(option)) == 0
safe_call success: 80 bind(listen_fd,(__const struct sockaddr *)&saddr,sizeof(saddr)) == 0
safe_call success: 81 listen(listen_fd,n) == 0
start thread(0)
safe_call success: 58 accept(listen_fd,nullptr,nullptr) == 4
safe_call success: 61 read(accept_fd,buffer,sizeof(uint64_t)) == 5
safe_call success: 66 write(accept_fd,ptr,1024) == 1024
safe_call success: 66 write(accept_fd,ptr,1024) == 1024
safe_call success: 66 write(accept_fd,ptr,1024) == 1024
safe_call success: 66 write(accept_fd,ptr,1024) == 1024
safe_call success: 66 write(accept_fd,ptr,1024) == 1024
safe_call success: 66 write(accept_fd,ptr,1024) == 1024
safe_call success: 66 write(accept_fd,ptr,1024) == 1024
safe_call success: 66 write(accept_fd,ptr,1024) == 1024
safe_call success: 66 write(accept_fd,ptr,1024) == 1024
safe_call success: 66 write(accept_fd,ptr,1024) == 1024

я компилял и пускал это под 32 битами

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

1. перед sin_family и товарищи старпёрского префикса нет — т.е. все точно как в designated initializer-ах (хотя и это в общем-то похрен, поскольку в хедере)

Ну что за идиот. Он насрал 9 строк, чтобы сократить 3.

2. вообще все до /// end of unix_syscall.hpp можно пропустить, т.к. это тонкая обертка, а настоящий код внизу и легко читабелен для сишника

Тонкую обёртку спастил у меня и насрал дерьма сверху - молодец.

int id)
fprintf( stderr, "start thread(%lu)\n", id );//да, профессионал.

threads[id] = std::thread( worker, listen_fd, id );//просто феерично.

for(int id=0; id<n; ++id )// а это не менее.

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

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

Не нужно. Задача кода продемонстрировать работоспособность концепции.

ну вот, типично царский ответ: любой баг в царском говнокоде оправдывать тем, что это «не нужно»

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

Спаси меня от свой убогости. Пускал он. Я тебе говорил, что тебе надо. Ты себе мануал пусти - это тебе поможет. Если ты не понимаешь смысл кода - зачем ты пытаешься что-то выкатывать? Зачем ты из него пытаешься убирать «лишние» вещи, назначение которых ты не понимаешь?

Ты действительно не понимаешь этого? Я явно переоценил твои умственные способности. Хотя я предполагал, конечно, чтоб до такой степени. Мда...

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

Вот видишь как просто, когда у тебя реально есть что сказать.

То, что мне было тебе сказать я сказал. Твоя портянка выглядела как индусский говнокод, в ней я колупаться не особо хотел, потому сообщил о том, что заметил. А что тебе непонятно в термине «декомпозиция» в контексте применения к процедуре worker() я не могу понять.

И что произошло в ситуации со мною.

ты написал на плюсах, молодец

Поэтому не надо так. Хорошо?

Хочу обратить твоё внимание, что за всё время общения с тобою я НИ РАЗУ тебя оскорбил, хотя ты поливал меня (и других людей) помоями регулярно и в кажом посте.

Разницу чувствуешь?

Что удивительно, это то - как у тебя горит. Мне реально насрать на оскорбления, я могу спокойно общаться даже в такой гнусной атмосфере, а у тебя полыхает от каждого поста. Что с тобой не так, парень?

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

ну вот, типично царский ответ: любой баг в царском говнокоде оправдывать тем, что это «не нужно»

Баг? Ну дак покажи мне баг, балабол. Ты нашёл баг - хорошо. Что такое баг - ошибка в программе, которая инвалидирует её результат. Ну дак объясни мне - где и в чём у меня баг - вперёд.

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