Why shouldn't I use volatile for synchronization between threads?

Asked 2 years ago, Updated 2 years ago, 39 views

To synchronize the two threads in C language, I wrote a program similar to the following:

 volatile int hoge=0;
//...
void fuga1() // running on thread 1
{
    while(1)
    {
        while(hoge==0)// Wait for the value to change
            sleep(1);
        puts("fuga1!");
        hoge = 0;
    }
}

void fuga2()// working on thread 2
{
    while(1)
    {
        sleep(1000);// Wait 1 second
        hoge = 1;
    }
}

This program is running without any problems and prints "fuga1" every second.

However, I have heard that this is not the correct way to use volatile and that volatile should not be used for synchronization between threads.Could someone tell me exactly why?

c

2022-09-30 20:27

4 Answers

Inter-thread synchronization with the volatile variable is due to unguaranteedto work as expected in any environment (compiler, OS).

As mentioned in the question, certain compilers on certain operating systems may work as expected, but there is no standard (specification) that ensures that the variable = inter-thread synchronization works.For example, there is no such definition in the C language specification, and there is no such definition in the POSIX or OpenMP specifications above the C language.

One of the most misleading things about the behavior of the volatile variable is that in many environments the volatile variable appears to be working as an inter-thread synchronization, despite no specifications guarantee.However, since it just happened to work as expected, it leads to "this is not the right way to use volatile" and "don't use volatile to synchronize between threads."

See also Do not use POS03-C.volatile as a synchronization primitive in JPCERT.Also, the article that @kazuto referred to mentioned C++ language, but you can apply C language as it is, so please refer to it.

Supplement: If Microsoft Visual C++ 2005 or later is used on x86 architecture (including x86-64), it acts as a proprietary extension for VC++, the volatile variable=inter-thread synchronization.However, as the new C++11/C11 language specification was developed, atomic variables were defined as standard, so This proprietary extension should not be actively used.


2022-09-30 20:27

As mentioned in other answers, volatile is intended to avoid the effects of compiler optimization and is not appropriate to use to synchronize threads.

If you look at the blog post below, you will understand why it is not appropriate.

http://i-saint.hatenablog.com/entry/20101005/1286208402

If you want to synchronize between threads, I think it is appropriate to use the condition variable (pthread_cond). Below is the code for using pthread_cond.

 inthoge=0;
pthread_mutex_tmutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_tcond = PTHREAD_COND_INITIALIZER;
//...
void fuga1() // running on thread 1
{
    while(1)
    {
        pthread_mutex_lock (&mutex);
        while(hoge==0)// Wait for the value to change
            pthread_cond_wait(&cond, & mutex);
        hoge = 0;
        pthread_mutex_unlock (&mutex);
        puts("fuga1!");
    }
}

void fuga2()// working on thread 2
{
    while(1)
    {
        sleep(1000);// Wait 1 second
        pthread_mutex_lock (&mutex);
        hoge = 1;
        pthread_cond_signal(&cond);
        pthread_mutex_unlock (&mutex);
    }
}


2022-09-30 20:27

I think volatile is just a way to prevent the compiler optimization from erasing the variables and is not a thread-safe feature. In other words, it may be because volatile should not be interpreted "wrongly" as thread safe.


2022-09-30 20:27

Discussion of the relationship between the volatile variable and multi-threaded (previous part) http://d.hatena.ne.jp/yohhoy/20121016/p1

I think this blog is also helpful, but it seems that the reason for using volatile is that it is not working due to environmental dependence, and that it is defined as undefined behavior in recent environments.


2022-09-30 20:27

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.