1

I'm having some thread programming learning on my virtual machine. The code that do not perform as expected is following:

#include <iostream>
#include <thread>
using namespace std;

void function01() {                                                                                                                   
      for (int i=0; i<100; i++) {                                                                                                   
               std::cout << "from t1:" << i << std::endl;                                                                            
      }                                                                                                                             
}   

int main() {
 // data race and mutex                                                                                                                                             
       std::thread t1( function01 );                                                                                                 
       for (int i=0; i<100; i++) {                                                                                                   
              std::cout << "from main:" << i << std::endl;                                                                          
       }                                                                                                                             
       t1.join();   
       return 0;
}

These code should make a data race on std output. But when I compiled it with

:!g++ -std=c++11 -pthread ./foo.cpp

and running, every time I got a result in which 100 times "t1" followed 100 times "main". What confusing me is that when I did the same thing on my another ubuntu14.04 which was installed in my old lap-top, the code performed as my expected. That means this code encountered with data race.

I don't know much about vmware. Are the threads running on the vmware are managed and won't encountered data race?

------------- second edit -----------------------

Thanks for everybody.

The quantity of core might be the main reason. And I had my expected result after setting quantity of vm core to more than one.

Community
  • 1
  • 1
Frank Wang
  • 788
  • 7
  • 23
  • 1
    I think your vm is only one-core of processor. In this case no code is executed in parallel, even if it should be. –  Mar 07 '16 at 13:41
  • Why do you think there should be a data race? Writing to `std::cout` does not introduce a data race. – Kerrek SB Mar 07 '16 at 13:47
  • @KerrekSB What I expected is the disorder for the two cout, which in this case are " from main " and "from t1". – Frank Wang Mar 07 '16 at 13:52
  • @Kilanny You may be right, my vm is only one-core. And this might mean that I can not use it as my learning tools. Thank you for your advice, which gives me the clue to find the answer. – Frank Wang Mar 07 '16 at 13:57
  • @FrankWang Try increasing its processor cores from VMware settings. –  Mar 07 '16 at 14:00
  • OK, I understand that, but please be sure that what you describe is not a data race. The term "data race" has very specific, important, technical meaning in C++, and your code doesn't have a data race in the technical sense. It merely may produce "interleaved output". – Kerrek SB Mar 07 '16 at 17:29

2 Answers2

2

Your new machine is probably much faster than your old one. So it is able to complete execution of function01 before main gets to its own loop.

Or it has only one CPU, so it can execute only one routine at a time. And because your loop requires really small amount of computation, CPU could be done with it in one slice of time given to it by OS.

Make sure that your VM has more than one CPU allocated to it. And try to make each step in your loops 'heavier'.

double accumulator = 0;
for (int i=0; i<100; i++) {
    for (int j=1; j<1000*1000; j++)
        accumulator += std::rand();
    std::cout << "from t1:" << i << std::endl;
}
Dennis
  • 2,615
  • 2
  • 19
  • 20
1

I think the problem is with the time slice. You can verify it by yourself, by introducing some delay in your code. For example:

#include <iostream>
#include <chrono>
#include <thread>

void function01() {
    for (int i=0; i<100; i++) {            
       std::cout << "from t1:" << i << std::endl;
       std::this_thread::sleep_for(std::chrono::duration<double, std::milli>{10});
    }
}   

int main() {
   // data race and mutex
   std::thread t1( function01 );
   for (int i=0; i<100; i++) {
       std::cout << "from main:" << i << std::endl;
       std::this_thread::sleep_for(std::chrono::duration<double, std::milli>{10});
   }

   t1.join();   
   return 0;
}
Amadeus
  • 10,199
  • 3
  • 25
  • 31