이것은 좋은 질문입니다.
첫째, C ++ 98 / C ++ 03에는 "스레드"개념이 없습니다. 그래서 그 세상에서 질문은 무의미합니다.
C ++ 0x는 어떻습니까? Martinho의 답변을 참조하십시오 (나는 놀랐습니다).
C ++ 0x 이전의 특정 구현은 어떻습니까? 예를 들어 다음은 basic_streambuf<...>:sputcGCC 4.5.2 ( "streambuf"헤더) 의 소스 코드입니다 .
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;
}
분명히 이것은 잠금을 수행하지 않습니다. 그리고 둘 다 그렇지 않습니다 xsputn. 그리고 이것은 확실히 cout이 사용하는 streambuf 유형입니다.
내가 알 수있는 한 libstdc ++는 스트림 작업에 대해 잠금을 수행하지 않습니다. 그리고 나는 느리기 때문에 어떤 것도 기대하지 않을 것입니다.
그래서이 구현으로, 분명히 다른 각 손상 (두 개의 스레드 '출력 가능 하지 만 인터리브).
이 코드가 데이터 구조 자체를 손상시킬 수 있습니까? 대답은 이러한 기능의 가능한 상호 작용에 따라 다릅니다. 예를 들어, 한 스레드가 버퍼를 플러시하려고하는 동안 다른 스레드가 호출을 시도하면 어떻게됩니까 xsputn? 컴파일러와 CPU가 메모리로드 및 저장 순서를 재정렬하는 방법에 따라 달라질 수 있습니다. 확인하려면 신중한 분석이 필요합니다. 또한 두 스레드가 동시에 동일한 위치를 수정하려고 할 때 CPU가 수행하는 작업에 따라 다릅니다.
즉, 현재 환경에서 제대로 작동하더라도 런타임, 컴파일러 또는 CPU를 업데이트하면 중단 될 수 있습니다.
요약 : "하지 않을 것". 적절한 잠금을 수행하는 로깅 클래스를 빌드하거나 C ++ 0x로 이동하십시오.
약한 대안으로 cout을 unbuffered로 설정할 수 있습니다. (보장되지는 않지만) 버퍼와 관련된 모든 로직을 건너 뛰고 write직접 호출 할 가능성이 있습니다. 엄청나게 느릴 수 있지만.