Je suis un développeur C++ qui a principalement programmé sur Solaris et Linux jusqu'à récemment, lorsque j'ai été contraint de créer une application destinée à Windows.Existe-t-il un moyen d'obtenir une insertion/extraction de flux sans verrouillage sur basic_iostream dans Windows?
J'ai utilisé une conception de communication basée sur le flux d'E/S C++ soutenu par socket TCP. La conception est basée sur un seul thread continuellement lu à partir du flux (la plupart du temps bloqué dans le socket en attente de lecture des données) tandis que les autres threads envoient à travers le même flux (synchronisé par mutex). Lorsque je suis passé à Windows, j'ai choisi d'utiliser boost :: asio :: ip :: tcp :: iostream pour implémenter le flux de socket. J'ai été consterné de constater que la conception multithread ci-dessus a abouti à l'impasse sur Windows. Il semble que le operator<<(std::basic_ostream<...>,std::basic_string<...>)
déclare un «Sentry» qui verrouille le flux entier pour les opérations d'entrée et de sortie. Étant donné que mon thread de lecture attend toujours sur le flux, envoyer des opérations à partir d'autres threads blocage lorsque ce Sentry est créé.
Voici la partie pertinente de la pile d'appel au cours de l'opérateur < < et la construction 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++
...
je serais bien si les composants IStream et ostream ont été enfermés séparément, mais ce n'est pas le cas.
Existe-t-il une implémentation alternative des opérateurs de flux que je peux utiliser? Puis-je lui ordonner de ne pas verrouiller? Dois-je implémenter le mien (je ne sais pas comment le faire)?
Toutes les suggestions seraient appréciées.
(Plate-forme est Windows 32 bits et 64 bits. Comportement observé avec Visual Studio 2003 Pro et 2008 Express)
+1 Bonne question, bien formulé. Dommage que je n'ai pas de réponse pour toi! –