Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need to use volatile keyword if I declare a variable between mutexes and return it?

Tags:

c++

Let's say I have the following function.

std::mutex mutex;

int getNumber()
{
    mutex.lock();
    int size = someVector.size();
    mutex.unlock();
    return size;
}

Is this a place to use volatile keyword while declaring size? Will return value optimization or something else break this code if I don't use volatile? The size of someVector can be changed from any of the numerous threads the program have and it is assumed that only one thread (other than modifiers) calls getNumber().

like image 771
Etherealone Avatar asked May 04 '13 17:05

Etherealone


People also ask

When should I use volatile in C++?

volatile was specifically intended to be used when interfacing with memory-mapped hardware, signal handlers, and the setjmp machine code instruction. This makes volatile directly applicable to systems-level programming rather than normal applications-level programming.

Does synchronization technics are required for volatile variable?

Noncompliant Code Example However, volatile flag still fails to provide the atomicity and visibility guarantees needed for synchronization primitives to work correctly. The volatile keyword does not promise to provide the guarantees needed for synchronization primitives.

What is the use of volatile keyword in multithreading?

Volatile keyword is used to modify the value of a variable by different threads. It is also used to make classes thread safe. It means that multiple threads can use a method and instance of the classes at the same time without any problem. The volatile keyword can be used either with primitive type or objects.

How do you declare a volatile variable in Java?

The volatile modifier is used to let the JVM know that a thread accessing the variable must always merge its own private copy of the variable with the master copy in the memory. Accessing a volatile variable synchronizes all the cached copied of the variables in the main memory.


Video Answer


2 Answers

No. But beware that the size may not reflect the actual size AFTER the mutex is released.

Edit:If you need to do some work that relies on size being correct, you will need to wrap that whole task with a mutex.

like image 51
Mats Petersson Avatar answered Sep 23 '22 03:09

Mats Petersson


You haven't mentioned what the type of the mutex variable is, but assuming it is an std::mutex (or something similar meant to guarantee mutual exclusion), the compiler is prevented from performing a lot of optimizations. So you don't need to worry about return value optimization or some other optimization allowing the size() query from being performed outside of the mutex block.

However, as soon as the mutex lock is released, another waiting thread is free to access the vector and possibly mutate it, thus changing the size. Now, the number returned by your function is outdated. As Mats Petersson mentions in his answer, if this is an issue, then the mutex lock needs to be acquired by the caller of getNumber(), and held until the caller is done using the result. This will ensure that the vector's size does not change during the operation.


Explicitly calling mutex::lock followed by mutex::unlock quickly becomes unfeasible for more complicated functions involving exceptions, multiple return statements etc. A much easier alternative is to use std::lock_guard to acquire the mutex lock.

int getNumber()
{
    std::lock_guard<std::mutex> l(mutex); // lock is acquired
    int size = someVector.size();
    return size;
} // lock is released automatically when l goes out of scope
like image 24
Praetorian Avatar answered Sep 21 '22 03:09

Praetorian