Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> boost::asio::io_service.run() и много блокировок 
:(
    Опции темы
phprus
Дата 17.11.2012, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 22.8.2006

Репутация: 1
Всего: 3



Доброго времени суток!

Написал я некоторый сервер с использованием boost.asio по модели, когда есть один экземпляр io_service и пул потоков по числу cpu, каждый из которых выполняет run().

Профилирование сервера показало просто дикое число блокировок мутексов и условных переменных внутри ASIO при использовании epoll. Сейчас на маленьких тестах это миллионы блокировок, на больших тестах и при нормальной работе будут миллиарды, что душу явно не греет и не факт, что способствует использованию всех 4-х ядер существующей железки и всех 20 планируемой.

Почитав документацию я увидел следующее http://www.boost.org/doc/libs/1_52_0/doc/h...ementation.html :
Цитата

Demultiplexing using epoll is performed in one of the threads that calls io_service::run(), io_service::run_one(), io_service::poll() or io_service::poll_one().

и похоже именно отсюда растут уши такого количества блокировок.

Подскажите пожалуйста, как с осознанием всего этого жить и есть ли выходы, лучшие чем переписывание на модель вида пул потоков в каждом из которых свой io_service и жестким распихиванием клиентов по этим io_service при подключении или еще какую-нибудь модель?
PM MAIL WWW ICQ   Вверх
mabrarov
Дата 17.11.2012, 18:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: 8
Всего: 9



Вот здесьздесь и здесь есть некоторые размышления на эту тему.

Вкратце, вы правы - придется применять "модель вида пул потоков в каждом из которых свой io_service и жестким распихиванием клиентов по этим io_service при подключении". Этот выбор можно и отложить на run time - см. проект echo_server (qt_echo_server) из https://asio-samples.svn.sourceforge.net/sv...o-samples/trunk.

Если же углубиться в детали, то "виновата" не библиотека Boost.Asio а сам epoll (точнее его реактивная идеология). В Windows, с его проактором на уровне ОС, я не смог повторить эту проблему.
PM MAIL WWW Skype   Вверх
phprus
Дата 17.11.2012, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 22.8.2006

Репутация: 1
Всего: 3



mabrarov,
Спасибо за ссылки, почитаю.

Цитата(mabrarov @  17.11.2012,  21:30 Найти цитируемый пост)
Вкратце, вы правы - придется применять "модель вида пул потоков в каждом из которых свой io_service и жестким распихиванием клиентов по этим io_service при подключении".

Значит придется применить...

Цитата(mabrarov @  17.11.2012,  21:30 Найти цитируемый пост)
Этот выбор можно и отложить на run time - см. проект echo_server (qt_echo_server) из

Немного не понял, что имеется ввиду?
Нечто отличное от выбора io_service в момент создания объекта-клиента? А выбор например циклический.


Цитата(mabrarov @  17.11.2012,  21:30 Найти цитируемый пост)
В Windows, с его проактором на уровне ОС, я не смог повторить эту проблему. 

А про Windows мануал говорит:
Цитата

Demultiplexing using I/O completion ports is performed in all threads that call io_service::run(), io_service::run_one(), io_service::poll() or io_service::poll_one().

Там такой проблемы и не должно быть судя по всему.
PM MAIL WWW ICQ   Вверх
mabrarov
Дата 19.11.2012, 00:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 100
Регистрация: 12.1.2011
Где: Казань

Репутация: 8
Всего: 9



Цитата(phprus @ 17.11.2012,  19:07)
Немного не понял, что имеется ввиду?
Нечто отличное от выбора io_service в момент создания объекта-клиента? А выбор например циклический.

Модель (одну из) 
  •  один экземпляр asio::io_service и пул рабочих потоков, работающих с этим единственным экземпляром
  •  по одному экземпляру asio::io_service на каждый рабочий поток (аля пул из asio::io_service)
можно выбирать в run time.

PM MAIL WWW Skype   Вверх
phprus
Дата 24.11.2012, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 22.8.2006

Репутация: 1
Всего: 3



Цитата(mabrarov @  19.11.2012,  03:22 Найти цитируемый пост)
можно выбирать в run time.

Да, действительно.


В итоге я остановился на следующей структуре приложения:
1) main_io_service - не занимается вообще ничем кроме как отслеживания сигналов операционной системы (SIGINT и т.д.), выполняется в главном потоке отвечает за управление модулями, корректное завершения приложения и т.д.
2) background_io_service и пул потоков, выполняющих background_io_service.run() - предназначен для выполнения тяжелых фоновых операций. Вспомогательные таймеры, загрузка/выгрузка на диск различных данных, с которыми можно оперировать в фоновом режиме.
3) пул потоков, в каждом свой io_service - для обслуживания сетевой активности. Сокет в момент создания прикрепляется к одному из потоков. Так как большинство моих действий при работе с сетью очень легкие, то это работает нормально даже не смотря на наличие некоторого количества mutex'ов для защиты общих структур данных. Вначале я беспокоился, что один глобальный mutex будет тормозить, но тестирование показало что до момента, когда я упрусь в него еще очень и очень долго (глобальный mutex защищает map объектов, которые нужно доставать по ключу, а так как map редко, но все-же меняется, то пришлось использовать mutex).
PM MAIL WWW ICQ   Вверх
borisbn
Дата 24.11.2012, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(phprus @  24.11.2012,  15:36 Найти цитируемый пост)
глобальный mutex защищает map объектов, которые нужно доставать по ключу, а так как map редко, но все-же меняется, то пришлось использовать mutex

посмотри Boost.shared_mutex
Цитата
The class boost::shared_mutex provides an implementation of a multiple-reader / single-writer mutex.

ИМХО как раз твой случай


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
phprus
Дата 25.11.2012, 10:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 22.8.2006

Репутация: 1
Всего: 3



borisbn
Спасибо за совет про Boost.shared_mutex, я про него правда знаю.
В ближайшее время посмотрю на сколько shared_mutex будет лучше.
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0750 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.