samedi 23 mai 2015

storing mutexes in a vector/deque c++

I would like to store a variable number of mutexes in a container like vector or deque.

In one of the use cases, I need to reliably and deadlock-free lock all of the mutexes. I would also like to have exception safety guarantee, that if an exception is thrown, all of the mutexes are as if no locking occured.

I am trying to do something like:

std::vector<std::mutex> locks_(n);
std::vector<std::lock_guard<std::mutex> > guards(n);
for(int i = 0; i < n; i++) {
    std::lock_guard<std::mutex> guard(locks_[i]);
    guards.emplace_back(std::move(guard));
}

but it doesn't compile, giving me:

/usr/include/c++/4.8/ext/new_allocator.h:120:4: error: use of deleted function ‘std::lock_guard<_Mutex>::lock_guard(const std::lock_guard<_Mutex>&) [with _Mutex = std::mutex]’

I guess there might also be a problem when lock_guards are destroyed, because the order must be reversed as compared to construction, but the standard saves us with:

The delete-expression will invoke the destructor (if any) for the object or the elements of the array being deleted. In the case of an array, the elements will be destroyed in order of decreasing address (that is, in reverse order of the completion of their constructor; see 12.6.2).

Are there any potential pitfalls with this approach and how can one make it work?

Edit

actually I am wrong, it seems vector does not guarantee a particular order of destruction. See this question: Order of destruction of elements of an std::vector

Aucun commentaire:

Enregistrer un commentaire