Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ID generator with local static variable - thread-safe?

Will the following piece of code work as expected in a multi-threaded scenario?

int getUniqueID()  
{  
    static int ID=0;  
    return ++ID;  
}

It's not necessary that the IDs to be contiguous - even if it skips a value, it's fine. Can it be said that when this function returns, the value returned will be unique across all threads?

like image 858
Poseidon Avatar asked Apr 24 '10 18:04

Poseidon


People also ask

Are local static variables thread-safe?

With C++11, static variables with block scope have an additional guarantee; they will be initialized in a thread-safe way.

Is static initialization thread-safe?

Starting in C++11, scoped static initialization is now thread-safe, but it comes with a cost: Reentrancy now invokes undefined behavior.] The rule for static variables at block scope (as opposed to static variables with global scope) is that they are initialized the first time execution reaches their declaration.

Are static members thread-safe C#?

They are not thread safe.


3 Answers

No, it won't. Your processor will need to do the following steps to execute this code:

  • Fetch value of ID from memory to a register
  • Increment the value in the register
  • Store the incremented value to memory

If a thread switch occurs during this (non atomic) sequence, the following can happen:

  • Thread a fetches the value 1 to a register
  • Thread a increments the value, so the register now contains 2
  • Context switch
  • Thread b fetches the value 1 (which is still in memory)
  • Context switch
  • Thread a stores 2 to memory and returns
  • Context switch
  • Thread b increments the value it has stored in its register to 2
  • Thread b (also) stores the value 2 to memory and returns 2

So, both threads return 2.

like image 114
FRotthowe Avatar answered Oct 05 '22 04:10

FRotthowe


No, there is still a potential for races, because the increment is not necessarily atomic. If you use an atomic operation to increment ID, this should work.

like image 21
WhirlWind Avatar answered Oct 05 '22 03:10

WhirlWind


If you just need some monotonically increasing (or very close to it) numbers across N threads, consider this (k is some number such that 2^k > N):

int getUniqueIDBase()  
{  
    static int ID=0;  
    return ++ID;  
}

int getUniqueID()
{
    return getUniqueIDBase() << k + thread_id;
}
like image 37
Yuliy Avatar answered Oct 05 '22 03:10

Yuliy