2

I have an application that continuously std::vector::push_back elements into a vector. As it is a real-time system I cannot afford it to stall at any time. Unfortunately, when the reserved memory is exhausted the push_back automatic memory allocation does cause stalls (up to 800ms in my measurements).

I have tackled the problem by having a second thread that monitors when the available memory and calls a std::vector::reserve if necessary.

My question is: is it safe to execute reserve and push_back concurrently?

(clearly under the assumption that the push_back will not reallocate memory)

Thanks!

andrea
  • 839
  • 3
  • 9
  • 16
  • 3
    Using a data structure which might grow by allocating memory and requiring real-time semantics is a contradiction in my book. There is no fixed upper bound on the duration of a memory allocation. – Micha Wiedenmann Apr 25 '14 at 09:13
  • 2
    You clearly use the wrong data structure. You need a concurrent, non-blocking queue. Unfortunately, the standard library doesn't provide it. You may be able to use the "thread building blocks" library. – stefan Apr 25 '14 at 09:15

2 Answers2

3

It is not thread-safe because a vector is contiguous and if it gets larger then you might need to move the contents of a vector to a different location in memory.

As suggested by stefan, you can look at non-blocking queues or have a list (or vector) of vectors such that when you need more space, the other thread can reserve a new vector for you while not blocking the original for lookups. You would just need to remap your indices to look up into the correct vector within the list.

sordid
  • 177
  • 6
  • That is not the only reason it is not thread safe. Even if there is no reallocation, the class invariants can get easily broken. Any write during concurrent access is undefined behaviour. – juanchopanza Apr 25 '14 at 13:30
  • True, but this is explaining the larger issue with what the poster wishes to do, and why even synchronizing the vector is not a solution to getting rid of the stalls. – sordid Apr 25 '14 at 13:37
  • This could lead OP to think that as long as there are no reallocations there is no problem. – juanchopanza Apr 25 '14 at 13:49
  • Isn't the OP's question about reallocations? It seems the highlighted part isn't what he really wanted to ask. Him taking my answer as correct supports that conclusion. :) – sordid May 01 '14 at 10:42
  • That doesn't make your answer right. OP taking your answer doesn't really mean anything. They are probably not aware that even with out reallocations this is unsafe. – juanchopanza May 01 '14 at 11:59
  • 1
    OP now just knows this is a sufficient condition for not being able to use std::vector for the task at hand. – andrea May 14 '14 at 13:31
-10

No.

Thread-safety concept exists only in C++11. And it is defined in relation to const. In C++11 standard library const now means thread-safe. Neither of those 2 methods is const, so no, it is not thread-safe.

bolov
  • 72,283
  • 15
  • 145
  • 224
  • ... What??? This is very, very wrong. First of all, the concept of thread safety has existed as long as there have been threads. C++11 brought library support with `std::thread`, but threads themselves have always existed (see [pthreads](https://en.wikipedia.org/wiki/POSIX_Threads)). Furthermore, while in general it is safe to call `const` methods in a threaded environment, since `const` methods cannot mutate state, non-const methods definitely _can_ be thread safe. One cannot point to a method not marked `const` and say that it is necessarily thread-unsafe. – Michael Dorst Oct 22 '19 at 22:54
  • @MichaelDorst The concepts of threads did not exist in the standard C++98/C++03. The abstract machine was fundamentally single threaded. This of course was in direct collision with the real world. So it fell into compiler implementers to kind of ignore this aspect of the standard and *enhance* the language with the concept of threads. Over this came threading libraries like pthreads. C++11 first and foremost brought the very concepts of threads into the language. Over this then it brought library support with `std::threads". See https://stackoverflow.com/questions/6319146/ – bolov Oct 22 '19 at 23:30
  • regarding the const and thread-safety. It was explained in a CppCon talk that in the standard library (since C++11 ofcourse) all const methods are thread safe and that they probably should have specified this in the standard. Unless otherwise specified a method is thread-safe iff it is const. I cannot remember which talk. I have a suspicion is this one: https://isocpp.org/blog/2012/12/you-dont-know-const-and-mutable-herb-sutter , but I don't have time to scroll through it. And this is a valid for the std only. – bolov Oct 22 '19 at 23:41
  • Yes, this is obviously true, since any code that does not change program state (that's what `const` means) is necessarily thread safe. However it is not true that all methods _not_ marked const are _not_ thread-safe. You said that they were not thread safe _because_ they were not marked `const`, which is false. It is true that they are not thread safe, but that is _not the reason why_. – Michael Dorst Oct 24 '19 at 03:29
  • Readers of your answers may well get the impression that they can tell the thread safety of an operation based on wether it is marked `const` or not. While the presence of `const` _does_ indicate thread safety, the _absence_ of it does not indicate thread-unsafety. A good example of this is [`std::mutex::lock()`](https://en.cppreference.com/w/cpp/thread/mutex/lock). This operation mutates state and therefore is not `const`, but the mutation is guaranteed to be atomic, and is therefore thread-safe. – Michael Dorst Oct 24 '19 at 03:32