C'est une grande question.
Tout d'abord, C++98/C++03 a pas la notion de "thread". Donc, dans ce monde, la question est dénuée de sens.
Qu'en C++0x? Voir Martinho de la réponse (qui je l'avoue m'a surpris).
Comment sur des implémentations spécifiques de pré-C++0x? Ainsi, pour exemple, voici le code source pour basic_streambuf<...>:sputc
de GCC 4.5.2 ("streambuf" header):
int_type
sputc(char_type __c)
{
int_type __ret;
if (__builtin_expect(this->pptr() < this->epptr(), true)) {
*this->pptr() = __c;
this->pbump(1);
__ret = traits_type::to_int_type(__c);
}
else
__ret = this->overflow(traits_type::to_int_type(__c));
return __ret;
}
Clairement, ce n'effectue aucun verrouillage. Et n' xsputn
. Et c'est certainement le type de streambuf que le cout utilise.
Aussi loin que je peux dire, libstdc++ effectue pas de verrouillage autour de l'un quelconque des flux d'opérations. Et je ne voudrais pas que tout, que serait lente.
Donc, avec cette mise en œuvre, évidemment, il est possible pour les deux fils de sortie de corrompre les uns des autres (pas seulement interleave).
Ce code pourrait-il endommager la structure de données elle-même? La réponse dépend des interactions possibles de ces fonctions; par exemple, ce qui se passe si un thread essaie de vider la mémoire tampon pendant que l'autre essaie de l'appeler xsputn
ou quoi que ce soit. Il peut dépendre de la façon dont votre compilateur et le CPU décider de réorganiser la mémoire des charges et les magasins; il faudrait une analyse minutieuse pour être sûr. Il dépend aussi de ce que votre CPU ne si deux threads tentent de modifier le même endroit en même temps.
En d'autres termes, même si elle arrive à fonctionner correctement dans votre environnement actuel, il pourrait casser lorsque vous mettez à jour votre runtime, compilateur, ou CPU.
Résumé: "je ne le ferais pas". Construire une classe de log qui n'bon verrouillage, ou de passer à C++0x.
Comme une faiblesse de l'alternative, vous pouvez définir le cout pour sans tampon. Il est probable (mais pas garanti) qui serait ignorer que la logique liée à la mémoire tampon et appelez - write
directement. C'est peut-être trop lent.