Я разработчик на C++, который в основном запрограммирован на Solaris и Linux до недавнего времени, когда мне пришлось создать приложение, предназначенное для Windows.Есть ли способ получить неблокирующую вставку/извлечение потока в basic_iostream в Windows?
Я использую коммуникационный дизайн, основанный на потоке ввода-вывода C++, поддерживаемый сокетом TCP. Конструкция основана на непрерывном непрерывном потоке потока из потока (большую часть времени блокируется в считываемом соке, ожидающем данные), в то время как другие потоки посылают через тот же поток (синхронизированный с помощью мьютекса).
При переходе к окнам я решил использовать boost :: asio :: ip :: tcp :: iostream для реализации потока сокетов. Я с тревогой обнаружил, что вышеупомянутый многопоточный дизайн привел к тупиковой ситуации в Windows. Похоже, что operator<<(std::basic_ostream<...>,std::basic_string<...>)
объявляет «Sentry», который блокирует весь поток для операций ввода и вывода. Поскольку мой прочитанный поток всегда ждет в потоке, отправляйте операции из других потоков в тупик, когда этот Sentry создан.
Вот соответствующая часть стека вызовов во время оператора < < и сторожевого строительства:
...
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 компоненты были заперты отдельно, но это не так.
Есть ли альтернативная реализация операторов потока, которые я могу использовать? Могу ли я направить его не на блокировку? Должен ли я реализовать свои собственные (не уверен, как это сделать)?
Любые предложения будут оценены.
(Платформа 32- и 64-битными. Поведение наблюдается с Visual Studio 2003 Pro и 2008 Express)
+1 Большой вопрос, хорошо сформулированы. Жаль, что у меня нет ответа для вас! –