1

I return to c++ programming, therefore, I am trying a lot of things to master new c++ standard. I know the code I provided is very bad. I think I know how to fix it.

code:

#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;
}

one kind of outputs:

!!!Hello World!!!
aaa
aaa

from the code, we can see the "aaa" should be printed once. my question is why there are two "aaa" on the output. what cause this problem?

many thanks

edit: added system info:

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) 

some other outputs:

type A:

!!!Hello World!!!
aaaaaa

typeB:

!!!Hello World!!!

typeC:

!!!Hello World!!!
aaaaaa

typeD:

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

edit: according @mark's answer. this is an undefined behavior.
I added a "sleep(1);" before main return. it gives me only one type of output. now i got confused, if it is undefined, why i didnt see other types of output?

output:

!!!Hello World!!!
aaa
cppython
  • 1,209
  • 3
  • 20
  • 30
  • This seems strange, I can't reproduce it on my system. I sometimes get *no* `"aaa"`s, but that makes sense because the main thread can exit before the detached thread has the chance to display its message. – us2012 Sep 12 '13 at 19:42
  • Isn't it an undefined behavior to exit when you have detached threads still running? – Gene Bushuyev Sep 12 '13 at 22:39

1 Answers1

3

std::cout is not thread safe unless you are using a real c++11 compiler. You can't have 2 threads writing to cout without protection. If you do, you will get undefined behavior -- just like you see!

See this discussion: Is cout synchronized/thread-safe?

c++11 does not appear to be fully supported until gcc 4.7, and you have gcc 4.6

Community
  • 1
  • 1
Mark Lakata
  • 19,989
  • 5
  • 106
  • 123
  • This is false. C++ specifies that concurrent access to the standard stream objects (i.e., cin, cout, cerr, clog, wcin, wcout, wcerr, wclog) shall not cause a data race. See C++11 27.4.1/4. – bames53 Sep 12 '13 at 21:09
  • please help to answer the latest question i appended on my question. thanks a lot – cppython Sep 13 '13 at 00:01
  • @cppython it's hard to understand what you're asking here. Undefined behavior just means that the standard doesn't dictate what happens so the compiler and OS can just do whatever they want, including crashing or working as you think it should. Just because there is a race-condition doesn't mean that you'll see it happen. The undefined behavior btw. was possibly having the program end before the detached thread ended. – PeterT Sep 13 '13 at 04:13
  • @PeterT, thanks. I am new to c++ , therefore, i try to understand anything i saw from output :) – cppython Sep 13 '13 at 17:30