Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transfer a value from one thread to another without locks

In the code snippet below, SetValue() is called by a thread when a certain value changes, and GetValue() is called by another thread to retrieve that value. My question is, are there any circumstances where GetValue() would return a spurious result?

double g_value[2];

// Thread one calls this to set the value
void SetValue( double value )
{
    g_value[0] = value;
    g_value[1] = value;
}

// Thread two calls this to get the value
double GetValue()
{
    double value[2];
    do
    {
        value[0] = g_value[0];
        value[1] = g_value[1];
    }
    while ( value[0] != value[1] );

    return value[0];
}
like image 868
CarlJohnson Avatar asked Mar 26 '26 21:03

CarlJohnson


1 Answers

There is no guarantee by the C standard that this leads to reasonable results. As you have written it, it might be even subject to optimizations, when the compiler has the impression that it knows the last stored value of your global variable.

But even if you'd declare your global variable volatile you could have surprises. The result of your comparison depends on cache lines, cache coherence, partial loads and a whole lot of things that you can't control easily. In addition, the result is completely architecture dependent.

Modern C, AKA C11, has _Atomic for the task that you want to achieve, and all modern processors support atomic features. Use these, or protect your variable by a mutex, read-write lock or similar.

like image 194
Jens Gustedt Avatar answered Mar 29 '26 11:03

Jens Gustedt