patterncppMinor
Recursive shared mutex
Viewed 0 times
recursivemutexshared
Problem
I've been looking for an implementation of a
Because boost and the stdlib does not have this special type, I wrote one myself. However, I am not sure if I missed something...
You find the full implementation with tests at github. Tested with GCC 5.4.
Features
recursive_shared_mutex.hpp
```
/*
* Copyright (c) 2017 Toni Neubert, all rights reserved.
*/
#pragma once
#include
#include
#include
#include
class RecursiveSharedMutex {
public:
/**
* @brief Constructs the mutex.
*/
RecursiveSharedMutex();
/**
* @brief Locks the mutex for exclusive write access for this thread.
* Blocks execution as long as write access is not available:
other thread has write access
other threads try to get write access
other threads have read access
*
* A thread may call lock repeatedly.
* Ownership will only be released after the thread makes a matching number of calls to unlock.
*/
void lock();
/**
* @brief Locks the mutex for sharable read access.
* Blocks execution as long as read access is not available:
other thread has write access
other threads try to get write access
*
* A thread may call lock repeatedly.
* Ownership will only be released after the thread makes a matching number of calls to unlock_shared.
*/
void lock_shared();
/**
* @brief Unlocks the mutex for this thread if its level
recursive shared mutex to handle a very special data tree inside a heavy multi-threaded application.Because boost and the stdlib does not have this special type, I wrote one myself. However, I am not sure if I missed something...
You find the full implementation with tests at github. Tested with GCC 5.4.
Features
- Recursive for exclusive ownership with lock and lock_shared.
- Recursive for sharable ownership with lock_shared.
- Threads trying to get exclusive ownership have a higher priority then new threads trying to get sharable ownership.
- Maximum waiting writers, level of ownerships: uint32::max
recursive_shared_mutex.hpp
```
/*
* Copyright (c) 2017 Toni Neubert, all rights reserved.
*/
#pragma once
#include
#include
#include
#include
class RecursiveSharedMutex {
public:
/**
* @brief Constructs the mutex.
*/
RecursiveSharedMutex();
/**
* @brief Locks the mutex for exclusive write access for this thread.
* Blocks execution as long as write access is not available:
other thread has write access
other threads try to get write access
other threads have read access
*
* A thread may call lock repeatedly.
* Ownership will only be released after the thread makes a matching number of calls to unlock.
*/
void lock();
/**
* @brief Locks the mutex for sharable read access.
* Blocks execution as long as read access is not available:
other thread has write access
other threads try to get write access
*
* A thread may call lock repeatedly.
* Ownership will only be released after the thread makes a matching number of calls to unlock_shared.
*/
void lock_shared();
/**
* @brief Unlocks the mutex for this thread if its level
Solution
One thought I had on this: wouldn't it play nicer if there was a thread yield outside the mutex in the tight for-loops? Or perhaps we scale up to that?
I've also been using this
I've also been using this
try_lock addition;bool RecursiveSharedMutex::try_lock() {
auto threadId = std::this_thread::get_id();
std::thread::id emptyThreadId;
std::lock_guard lock(_mtx);
if (_writerThreadId == threadId) {
++_writersOwnership;
return true;
}
if (_readersOwnership.size() == 0 && _writerThreadId.compare_exchange_weak(emptyThreadId, threadId))
return true;
return false;
}Code Snippets
bool RecursiveSharedMutex::try_lock() {
auto threadId = std::this_thread::get_id();
std::thread::id emptyThreadId;
std::lock_guard<std::mutex> lock(_mtx);
if (_writerThreadId == threadId) {
++_writersOwnership;
return true;
}
if (_readersOwnership.size() == 0 && _writerThreadId.compare_exchange_weak(emptyThreadId, threadId))
return true;
return false;
}Context
StackExchange Code Review Q#161735, answer score: 2
Revisions (0)
No revisions yet.