| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Программирование под Unix/Linux > Потоковый сервер на С++ |
| Автор: kiruhin 1.4.2013, 21:48 | ||
| Добрый день. Стала задача написать сервер на плюсах (под линукс). Признаться, данный язык только начал осваивать, поэтому могу показаться совсем уж нубом (за что прошу больно не пинать 1. Реализация потокового (pre-thread) сервера на С++ под Linux (GNU) 2. В данном случае не оговариваются действия сервера (его логика - это сам осилю), а только грамотное построение модели (принял - передал) 3. Подчеркиваю - код для Linux Начал с того, что гуглил много. В итоге нашел некий "пример" (код ниже), который взял за основу, которую в последствии буду "допиливать". Итак, код был взят отсюда: http://www.unix.com/programming/17611-multi-threaded-server-pthreads-sleep.html Дублирую код в топик:
Сам автор этого кода, в своем посте пишет: "I am trying to writa a multi-client & multi-threaded TCP server. There is a thread pool. Each thread in the pool will handle requests of multiple clients. But here I have a problem. I find a solution but it is not how it must be... i think. When threads working without sleep(1) I can't get response from server but when I put sleep(1) in thread function as you will see in code, everything works fine and server can make echo nearly for 40000 clients between 1 or 2 seconds. What am I doing wrong here? " И это действительно так. С одной оговоркой, что если заккоментировать sleep(1), то это сервер работает именно так, как нужно, НО вводит систему в ступор (загрузка ЦП 100%, что очевидно, т.к. while(1) ) С другой стороны, из-за этого sleep(1), во-первых, ответ сервера возвращается только через секунду, во-вторых, если передать серверу несколько пакетов (передать быстро), то он "склеит" это пакеты в один, как следствие, пакеты невозможно будет разобрать. Пожалуйста, подскажите: 1. Если приведенный пример (код, взятый за основу) корректный - как можно избежать sleep (1)? 2. Если код в своей основе неверный (или морально устарел, т.к. пост датируется аж 2005 годом) - помогите собрать этот покотовый сервер (хоть пример реально работающего) 3. Обязательно ли объявлять сокет неблокируемым (как в приведенном примере)? Спасибо огромное! |
| Автор: dershokus 2.4.2013, 10:53 | ||||||
Вот тут плохо
Это всеравно что написать программу с бесконечным циклом.
Т.е. делать это ничего не будет но грузить ЦП будет на 100%. Если долго не париться, то можно написать так:
А вообще все треды должны спать по идее, если пользователя нет и управляющий тред при новом клиенте должен пробуждать тред куда кинул этого клиента. Как-то так. |
| Автор: fish9370 2.4.2013, 12:23 |
| смысла от неблокируемости в данной реализации нет, неблокируемость нужна, чтобы делать параллельно что-то еще.. ошибка номер один - нет проверки EINTR - чтение нужно повторить два - кривое обнуление буфера "memset( (char *) &buffer, 0, strlen(buffer))" - собственно зачем оно? три - задержки сбоку ввиде sleep - кривое решение собственно, архитектура не верная - 300 потоков крутятся в холостую -> решается вставкой проверки на присутствие данных (select/poll/epoll) повторюсь, неблокируемость в этом случае вред, в этом нет никакого смысла хорошо бы понять, с какими потоками данных будут иметь дело треды, интенсивность, в какую сторону преобладать - это тоже важно PS, это не Си++, это чистый Си Добавлено через 9 минут и 12 секунд еще бы рекомендовал взглянуть на системные вызовы readv/writev, возможно в данной задаче они будут как никто другой уместны.. |
| Автор: Acer 2.4.2013, 16:33 | ||
А как еще можно реализовать такую систему без sleep или usleep? |
| Автор: dershokus 2.4.2013, 19:04 | ||
В смысле именно в такой реализации? Можно семафор поставить и ждать пока его откроют (если я правильно все понял). Вообще как-то глупо вешать на тред какое-то количество пользователей и в цикле их обходить (вдруг только один пользователь есть?), epoll выглядит здесь уместнее IMHO. |
| Автор: bsa 3.4.2013, 15:40 |
| kiruhin, http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio.html. Начни с примеров. |