Это длинный вопрос. TL; DR: Я не знаю, как правильно разрабатывать программы, используя asio.Как упростить многопоточный дизайн с помощью asio?
Люди написали GUI-обертки для служебных программ CLI. Я пишу «прокси» для такой утилиты, которая передает команды, выпущенные графическим интерфейсом, на другую копию утилиты, запущенной на удаленном компьютере (через другой «прокси» на удаленном компьютере).
настоящее время я использую ASIO для сокета I/O, но я использую простой цикл в main()
для выполнения блокировки чтения из stdin
(асинхронный ввод/вывод не представляется возможным на stdin
& друзей на Windows). Я попытался разделить все, используя простой механизм pub/sub. Абоненты сообщений запускаются в своих потоках и получают сообщения от std::deque
через std::condition_variable
. Я в настоящее время имеют следующие I/O связанных классов:
- SocketServer: Работает на собственном потоке, создает
asio::io_service
, связывается с & прослушивает порт, и принимает удаленные соединения. - SocketClient: Создает
asio::io_service
, подключается к удаленному хосту. & предоставляет пароль. - SocketConnection: Получает от SocketServer или SocketClient. Аутентификация удаленного хоста (только для сервера), чтение из сокета и запись в сокет при приеме
SocketOutputMessage
(в отдельном потоке). - ConsoleWriter: Выполняется в собственной ветке, записывается в
stdout
после полученияConsoleOutputMessage
.
Для меня главный недостаток этого дизайна в том, что есть слишком много потоков! SocketServer нуждается в собственном потоке из-за блокировки вызова asio::io_service::run()
. Аналогично, ConsoleWriter находится в своем собственном потоке, чтобы гарантировать, что все записи в stdout
происходят в одном потоке. Мне не нужен еще один поток для SocketConnection, но он нужен как следствие pub/sub. (Я хочу, чтобы сообщение всегда отправлялось на ))
Возможно, кто-нибудь предоставит мне предложения по оптимизации этой конструкции (и, надеюсь, уменьшите количество требуемых потоков)? С этой целью существуют ли какие-либо функции asio, о которых я должен знать? Пожалуйста, предоставьте пример кода и/или ссылки на соответствующие сайты или ответы SO, если сможете.
Cheers.