Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can an integer be shared between threads safely?

Is there a problem with multiple threads using the same integer memory location between pthreads in a C program without any synchronization utilities?

To simplify the issue,

  • Only one thread will write to the integer
  • Multiple threads will read the integer

This pseudo-C illustrates what I am thinking

void thread_main(int *a) {
  //wait for something to finish
  //dereference 'a', make decision based on its value
}

int value = 0;

for (int i=0; i<10; i++)
  pthread_create(NULL,NULL,thread_main,&value);
}
// do something
value = 1;

I assume it is safe, since an integer occupies one processor word, and reading/writing to a word should be the most atomic of operations, right?

like image 716
Mike Avatar asked Jan 03 '11 22:01

Mike


People also ask

Are integers thread safe?

Net all 32-bit types (e.g, int , bool , etc) are thread safe.

Are ints thread safe C++?

A good rule of thumb for choosing behaviour for a class in C++ is "do as int s do". With regard to thread safety, int s are simple: Any number of threads may read a given int concurrently. If any thread modifies a given int , no other threads may access that int for reading or writing concurrently.

How do you make increment thread safe?

In order to be thread safe you must declare the variable as follows: public static volatile int value; Now value being volatile, will be accessed in a synchronized block. Making the variable volatile is different from accessing it from a synchronized block.

What are thread safe operations?

Thread safety is a computer programming concept applicable to multi-threaded code. Thread-safe code only manipulates shared data structures in a manner that ensures that all threads behave properly and fulfill their design specifications without unintended interaction.


2 Answers

Your pseudo-code is NOT safe.

Although accessing a word-sized integer is indeed atomic, meaning that you'll never see an intermediate value, but either "before write" or "after write", this isn't enough for your outlined algorithm.

You are relying on the relative order of the write to a and making some other change that wakes the thread. This is not an atomic operation and is not guaranteed on modern processors.

You need some sort of memory fence to prevent write reordering. Otherwise it's not guaranteed that other threads EVER see the new value.

like image 75
Ben Voigt Avatar answered Sep 29 '22 13:09

Ben Voigt


Unlike java where you explicitly start a thread, posix threads start executing immediatelly.
So there is no guarantee that the value you set to 1 in main function (assuming that is what you refer in your pseudocode) will be executed before or after the threads try to access it.
So while it is safe to read the integer concurrently, you need to do some synchronization if you need to write to the value in order to be used by the threads.
Otherwise there is no guarantee what is the value they will read (in order to act depending on the value as you note).
You should not be making assumptions on multithreading e.g.that there is some processing in each thread befor accessing the value etc.
There are no guarantees

like image 31
Cratylus Avatar answered Sep 29 '22 11:09

Cratylus