Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does code mutating a shared variable across threads apparently NOT suffer from a race condition?

I'm using Cygwin GCC and run this code:

#include <iostream> #include <thread> #include <vector> using namespace std;  unsigned u = 0;  void foo() {     u++; }  int main() {     vector<thread> threads;     for(int i = 0; i < 1000; i++) {         threads.push_back (thread (foo));     }     for (auto& t : threads) t.join();      cout << u << endl;     return 0; } 

Compiled with the line: g++ -Wall -fexceptions -g -std=c++14 -c main.cpp -o main.o.

It prints 1000, which is correct. However, I expected a lesser number due to threads overwriting a previously incremented value. Why does this code not suffer from mutual access?

My test machine has 4 cores, and I put no restrictions on the program that I know of.

The problem persists when replacing the content of the shared foo with something more complex, e.g.

if (u % 3 == 0) {     u += 4; } else {     u -= 1; } 
like image 965
mafu Avatar asked Jan 23 '17 22:01

mafu


People also ask

What happens in multithreading due to race conditions?

When race conditions occur. A race condition occurs when two threads access a shared variable at the same time. The first thread reads the variable, and the second thread reads the same value from the variable.

Are race conditions possible in python?

There are many types of race conditions, although a common type of race condition is when two or more threads attempt to change the same data variable. NOTE: Race conditions are a real problem in Python when using threads, even in the presence of the global interpreter lock (GIL).

What is a race condition in C #?

A race condition exists when the success of your program depends on the uncontrolled order of completion of two independent threads. Suppose, for example, that you have two threads—one is responsible for opening a file and the other is responsible for writing to the file.


1 Answers

foo() is so short that each thread probably finishes before the next one even gets spawned. If you add a sleep for a random time in foo() before the u++, you may start seeing what you expect.

like image 113
Rob K Avatar answered Nov 08 '22 19:11

Rob K