2013-09-12 3 views
1

Я возвращаюсь к программированию на C++, поэтому я пробую много чего освоить новый стандарт C++. Я знаю, что код, который я предоставил, очень плох. Кажется, я знаю, как это исправить.C++ 11 thread unknown output

код:

#include <iostream> 
#include <thread> 

using namespace std; 

void apple (string const& x) 
{ 
       cout << "aaa" << endl; 
} 

void orange() 
{ 
       //string s = "hello"; 
       thread t(apple,"hello"); 
       t.detach(); 
} 

int main() { 
       orange(); 
       cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!! 
       return 0; 
} 

один вид выходов:

!!!Hello World!!! 
aaa 
aaa 

из кода, мы можем увидеть "ааа" должен быть напечатан один раз. Мой вопрос в том, почему на выходе есть два «aaa». что вызывает эту проблему?

большое спасибо

редактировать: добавил информацию о системе:

Using built-in specs. 
COLLECT_GCC=/usr/bin/g++ 
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.6.3/lto-wrapper 
Target: x86_64-redhat-linux 
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux 
Thread model: posix 
gcc version 4.6.3 20120306 (Red Hat 4.6.3-2) (GCC) 

некоторые другие выходы:

Тип A:

!!!Hello World!!! 
aaaaaa 

TypeB:

!!!Hello World!!! 

typeC:

!!!Hello World!!! 
aaaaaa 

типизированных:

!!!Hello World!!! 
aaa 
<empty line> 

редактировать: в соответствии ответ @ Марка. это неопределенное поведение.
Я добавил «сон (1)»; перед основным возвратом. он дает мне только один тип вывода. теперь я запутался, если он не определен, почему я не видел других типов вывода?

выход:

!!!Hello World!!! 
aaa 
+0

Это кажется странным, я не могу воспроизвести его в системе. Я иногда получаю * no * '" aaa "' s, но это имеет смысл, потому что основной поток может выйти до того, как выделенный поток сможет отобразить его сообщение. – us2012

+0

Разве это не неопределенное поведение для выхода, когда вы все еще работаете с отдельными потоками? –

ответ

3

std::cout не поточно, если вы не используете реальный C++ 11 компилятор. У вас не может быть двух потоков, записывающих в cout без защиты. Если вы это сделаете, вы получите неопределенное поведение - точно так же, как вы видите!

Смотрите эту дискуссию: Is cout synchronized/thread-safe?

C++ 11 не представляется, не будет полностью поддерживаться до gcc 4.7, и у вас есть GCC 4.6

+0

Это неверно. C++ указывает, что одновременный доступ к объектам стандартных потоков (т. Е. Cin, cout, cerr, clog, wcin, wcout, wcerr, wclog) не должен приводить к гонке данных. См. C++ 11 27.4.1/4. – bames53

+0

@ bames53 - Да, вы правы. Я уточнил свой ответ. –

+0

, пожалуйста, помогите ответить на последний вопрос, который я приложил к моему вопросу. Большое спасибо – cppython