3

I'm new to programming/C++ and I'm experimenting with simple multithreading. I have tried the following codes:

Example 1

#include <iostream>
#include <thread>         

void printFunc() {        
    while(1) {        
        std::cout << "threadOne Running..." << std::endl;           
    }
}        

int main() {
    std::thread threadOne(printFunc);            
    threadOne.detach();         

    while(1) {        
        std::cout << "main running..." << std::endl;        
    }
    return 0;
}

Example 2

#include <iostream>
#include <thread>         

void printFunc() {        
    while(1) {        
        std::cout << "threadOne running..." << std::endl;            
    }
}        

void initThread() {        
    std::thread threadOne(printFunc);            
    threadOne.detach();         
}         

int main() {        
    initThread();
    while(1) {        
        std::cout << "main running..." << std::endl;        
    }
    return 0;
}

When I run example 1 using Visual Studio in debug & release mode, it prints "main running..." most of the time and prints "threadOne running..." once in a while. But when I run example 2, it prints both of them (jumps between two prints "equally").

Edit:
Execution of example 1
Screenshot of execution of example 1

Execution of example 2

Screenshot of execution of example 2

Loga
  • 45
  • 7
  • Is it *consistent*? If you run the first program multiple times, does it always behave the same? How about the second program? – Some programmer dude Apr 16 '18 at 07:56
  • 3
    You might be experiencing something called a "thread convoy", but that could happen for both programs and should be fairly random. – Ulrich Eckhardt Apr 16 '18 at 07:56
  • 3
    The only difference is that the `thread` object is destroyed in #2. I can't see why that would matter once `detach()` has been called. – Jonathan Potter Apr 16 '18 at 08:02
  • @Someprogrammerdude Yes, I would say it is consistent in the way it behaves. – Loga Apr 16 '18 at 08:03
  • What happens if you add a sleep between creating the thread and the detach(); – Ol1v3r Apr 16 '18 at 08:53
  • @JonathanPotter "I can't see why that would matter" - other than the delay on the main thread. – UKMonkey Apr 16 '18 at 08:57
  • 2
    Tried both snippets in VS and both produce a random mess, no order whatsoever. – Killzone Kid Apr 16 '18 at 09:20
  • Both your programs are logically identical. The thread scheduling is the implementation detail - it might behave as you have observed on your machine with VS, but it also can behave differently with other compiler on another CPU. – pptaszni Apr 16 '18 at 09:49
  • @OliverCiappara I used `std::this_thread::sleep_for()`, there was not any noticeable changes. – Loga Apr 16 '18 at 10:24
  • @Loga I tried both your examples in VS2015 x86 Debug and both had the same expected behavior. Can you provide a screenshot of what you're seeing? – Ol1v3r Apr 16 '18 at 10:48
  • 1
    @OliverCiappara Added screenshot to the post. – Loga Apr 16 '18 at 11:45
  • 1
    Make the initThread method an inline function and see how it behaves. I am curious. – Rohit Walavalkar Apr 16 '18 at 12:18

1 Answers1

2

Possible reason for what you're seeing;

Because you did not specify which version of C++ you're using, I'll assume its C++11; As per Is cout thread-safe

Concurrent access to a synchronized (§27.5.3.4) standard iostream object’s formatted and unformatted input (§27.7.2.1) and output (§27.7.3.1) functions or a standard C stream by multiple threads shall not result in a data race (§1.10). [ Note: Users must still synchronize concurrent use of these objects and streams by multiple threads if they wish to avoid interleaved characters. — end note ]

Meaning that you still have to synchronize both cout streams. One way of doing that would be to wrap cout in your own class and assign it a mutex.

Ol1v3r
  • 758
  • 1
  • 10
  • 23
  • After reading a little more about C++ multithreading and trying the same examples with something else other than `std::cout`, it showed that it is actually the `cout streams` that causes the mess. Thanks. – Loga Apr 16 '18 at 15:30
  • That doesn't explain it. Firstly, in reply to @Loga, there is no mess that `cout` causes. Rather the opposite is the case, it manages to operate to some extent even though it is abused. Secondly, both of your programs abuse `cout` in the same way, so none of this explains the behaviour you describe. – Ulrich Eckhardt Apr 17 '18 at 05:17