Я разработчик на C ++, который до недавнего времени программировал преимущественно на Solaris и Linux, когда мне пришлось создавать приложение, ориентированное на Windows.
Я использовал коммуникационный дизайн, основанный на потоке ввода-вывода C ++, поддерживаемом сокетом TCP. Конструкция основана на том, что один поток постоянно читает данные из потока (большую часть времени блокирует чтение в сокете в ожидании данных), в то время как другие потоки отправляют через тот же поток (синхронизированный с мьютексом).
При переходе на окна я решил использовать boost :: asio :: ip :: tcp :: iostream для реализации потока сокетов. Я был встревожен, обнаружив, что вышеуказанный многопоточный дизайн привел к тупику в Windows. Похоже, что operator<<(std::basic_ostream<...>,std::basic_string<...>)
объявляет 'Sentry', который блокирует весь поток для операций ввода и вывода. Поскольку мой поток чтения всегда ожидает в потоке, операции отправки из других потоков блокируются при создании этого Sentry.
Вот соответствующая часть стека вызовов во время оператора << и построения Sentry: </p>
...
ntdll.dll!7c901046()
CAF.exe!_Mtxlock(_RTL_CRITICAL_SECTION * _Mtx=0x00397ad0) Line 45 C
CAF.exe!std::_Mutex::_Lock() Line 24 + 0xb bytes C++
CAF.exe!std::basic_streambuf<char,std::char_traits<char> >::_Lock() Line 174 C++
CAF.exe!std::basic_ostream<char,std::char_traits<char> >::_Sentry_base::_Sentry_base(std::basic_ostream<char,std::char_traits<char> > & _Ostr={...}) Line 78 C++
CAF.exe!std::basic_ostream<char,std::char_traits<char> >::sentry::sentry(std::basic_ostream<char,std::char_traits<char> > & _Ostr={...}) Line 95 + 0x4e bytes C++
> CAF.exe!std::operator<<<char,std::char_traits<char>,std::allocator<char> >(std::basic_ostream<char,std::char_traits<char> > & _Ostr={...}, const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & _Str="###") Line 549 + 0xc bytes C++
...
Было бы хорошо, если бы компоненты istream и ostream были заблокированы по отдельности, но это не так.
Есть ли альтернативная реализация потоковых операторов, которую я могу использовать? Могу ли я направить его, чтобы не заблокировать? Должен ли я реализовать свой собственный (не уверен, как это сделать)?
Любые предложения будут оценены.
(Платформа для Windows 32- и 64-разрядная. Поведение наблюдается в Visual Studio 2003 Pro и 2008 Express)