Will this be a non-interference in a multi-threaded environment?
In your question's text, dq
(like all the other variables in your function) is a local object:
std::deque<T> dq;
If this is really the case, then the question has an easy answer: "Yes". It is thread-safe because there is no contention: each thread works on a local object, and since there is no sharing, there can't be any data race.
Now assuming that your code intended to show the use of a shared data structure, and that dq
is actually a global object or something somehow accessible by several threads simultaneously (this is what the dq->size()
function call seems to suggest), then the answer is "It depends".
If all of your threads are concurrently executing only the function you are showing, and dq
is a reference or pointer to const
, so that your function doesn't contain any call to any non-const
member functions, then the answer is "Yes, but you don't really need any critical section at all in this case". Paragraph 17. 6.5.9/3 of the C++11 Standard specifies:
A C++ standard library function shall not directly or indirectly modify objects (1.10) accessible by threads
other than the current thread unless the objects are accessed directly or indirectly via the function’s non-const
arguments, including this
.
The reference to Paragraph 1.10 (and in particular to 1.10/21), which defines what a data races is, makes the meaning of the above Paragraph clearer:
The execution of a program contains a data race if it contains two conflicting actions in different threads,
at least one of which is not atomic, and neither happens before the other. Any such data race results in
undefined behavior. [...]
Finally, Paragraph 1.10/4 specifies when two actions are conflicting:
Two expression evaluations conflict if one of them modifies a memory location (1.7) and the other one
accesses or modifies the same memory location.
What follows from all this is that const
member functions are necessarily thread-safe. You may be interested in watching this presentation by Herb Sutter about it.
Since deque<T>::size()
is a const
member function, and at()
is a const
member function (because you are calling it from a reference or pointer to const
) which returns a reference to const
, there is no need to synchronize access from multiple threads.
If your dq
is not a reference or pointer to const
, then the answer is "No", because at()
is a non-const
member function. Moreover, since v
is a non-const reference to an element, your "operation on v
" could be non-const
, therefore introducing a data-race on the elements of dq
rather than on dq
itself.
Similarly, if your threads are concurrently accessing and modifying dq
through other functions, then the answer is again "No", because you are not protecting all the accesses to the shared object. Read operations conflict with write operations (see above), and you are only protecting some of them. In this case, your critical section should span the entire while
cycle.