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

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 the place to use the volatile keyword when declaring size? Will it return value optimization or something else to break this code if I don't use volatile? someVector can be resized from any of the many threads that the program has, and it is assumed that only one thread (other than modifiers) calls getNumber() .

+6
source share
3 answers

You did not specify what the type of the mutex variable is, but provided that it is std::mutex (or something similar to guarantee mutual exclusion), the compiler cannot perform many optimizations. This way, you don’t have to worry about optimizing the return value or some other optimization that allows you to execute a size() request outside the mutex block.

However, as soon as the mutex lock is released, another waiting thread can freely access the vector and possibly mutate it, thus changing its size. Now the number returned by your function is deprecated. As Mats Peterson says in his answer, if this is a problem, then the mutex lock should be received by the caller getNumber() and held until the caller is done using the result. This ensures that the size of the vector does not change during the operation.


The explicit call to mutex::lock , followed by mutex::unlock , quickly becomes impracticable for more complex functions related to exceptions, multiple return statements, etc. A simpler alternative is to use std::lock_guard to obtain a 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 
+5
source

No. But be careful that size may not reflect the actual size AFTER mutex output.

Edit: if you need to do some work based on size right, you will need to wrap this whole task with a mutex.

+8
source

Volatile is a keyword that you use to tell the compiler that it literally actually writes or reads a variable and does not apply any optimizations. Here is an example

 int example_function() { int a; volatile int b; a = 1; // this is ignored because nothing reads it before it is assigned again a = 2; // same here a = 3; // this is the last one, so a write takes place b = 1; // b gets written here, because b is volatile b = 2; // and again b = 3; // and again return a + b; } 

What is the real use of this? I saw this in the delay functions (the processor slowed down a bit, counting the number to the number) and in systems where several threads can look at the same variable. Sometimes this can help a little with multi-threaded things, but in fact it is not a piercing thing and, of course, not a silver bullet.

+1
source

Source: https://habr.com/ru/post/944284/


All Articles