Single Responsibility Principle: Should I separate my bibliography class in Reader, Writer and Container class?
Date : March 29 2020, 07:55 AM
I hope this helps you . I like the approach of separating "container" classes from reader/writer/getter and so on, preferably defined by an interface. Search for "strategy pattern" and you will find more information about it. A simple approach would be to have the Bibliography class accept an IBibliographyReader in its constructor, and then have a class implement that interface. When creating a Bibliography class you pass an instance of the concrete reader implementation to it.
|
Thread safety of multiple-reader/single-writer class
Tag : cpp , By : Caleb Ames
Date : March 29 2020, 07:55 AM
I hope this helps . This is an interesting use of shared_ptr to implement thread safety. Whether it is OK depends on the thread-safety guarantees of boost::shared_ptr. In particular, does it establish some sort of fence or membar, so that you are guaranteed that all of the writes in the constructor and insert functions of set occur before any modification of the pointer value becomes visible. I can find no thread safety guarantees whatsoever in the Boost documentation of smart pointers. This surprizes me, as I was sure that there was some. But a quick look at the sources for 1.47.0 show none, and that any use of boost::shared_ptr in a threaded environment will fail. (Could someone please point me to what I'm missing. I can't believe that boost::shared_ptr has ignored threading.)
|
Multiple-Reader, Single-Writer Lock in Boost WITH Writer Block
Tag : cpp , By : ArdentRogue
Date : March 29 2020, 07:55 AM
To fix the issue you can do The answer here almost does what I want. , Found it. I needed unique_lock instead of upgrade_to_unique_lock: boost::shared_mutex _access;
void reader()
{
// get shared access
boost::shared_lock<boost::shared_mutex> lock(_access);
}
void writer()
{
// wait for old shared access readers to finish
// but block out new shared access readers
boost::unique_lock<boost::shared_mutex> uniqueLock(_access);
}
|
How can I implement a C++ Reader-Writer lock using a single unlock method, which can be called be a reader or writer?
Tag : cpp , By : user107021
Date : March 29 2020, 07:55 AM
wish of those help Well, define two functions UnlockRead and UnlockWrite. I believe you do not need both accesses (Write/Read) at the same time in the same place. So what I am proposing is to have two other classes for locking access: class ReadWriteAccess
{
public:
ReadWriteAccess(uint32_t maxReaders);
~ReadWriteAccess();
uint32_t GetMaxReaders() const;
uint32_t GetMaxReaders() const;
eResult GetReadLock(int32_t timeout);
eResult GetWriteLock(int32_t timeout);
eResult UnlockWrite();
eResult UnlockRead();
private:
uint32_t m_MaxReaders;
Mutex* m_WriterMutex;
Semaphore* m_ReaderSemaphore;
};
class ReadLock
{
public:
ReadLock(ReadWriteAccess& access, int32_t timeout) : access(access)
{
result = access.GetReadLock(timeout);
}
eResult getResult() const { return result; }
~ReadLock()
{
if (result)
access.UnlockRead();
}
private:
ReadWriteAccess& access;
eResult result;
};
T someResource;
ReadWriteAccess someResourceGuard;
void someFunction()
{
ReadLock lock(someResourceGuard);
if (lock.getResult())
cout << someResource; // it is safe to read something from resource
}
class ReadWriteLock
{
public:
ReadWriteLock(uint32_t maxReaders);
~ReadWriteLock();
uint32_t GetMaxReaders() const;
eResult GetReadLock(int32_t timeout)
{
eResult result = GetReadLockImpl(timestamp);
if (result)
lockStack.push(READ);
}
eResult GetWriteLock(int32_t timeout)
{
eResult result = GetWriteLockImpl(timestamp);
if (result)
lockStack.push(WRITE);
}
eResult Unlock()
{
LastLockMode lockMode = lockStack.top();
lockStack.pop();
if (lockMode == READ)
UnlockReadImpl();
else
UnlockWriteImpl();
}
private:
uint32_t m_MaxReaders;
Mutex* m_WriterMutex;
Semaphore* m_ReaderSemaphore;
enum Mode { READ, WRITE };
std::stack<Mode> lockStack;
};
template <typename Value>
class MultiThreadStack
{
public:
void push(Value)
{
stackPerThread[getThreadId()].push(value);
}
Value top()
{
return stackPerThread[getThreadId()].top();
}
void pop()
{
stackPerThread[getThreadId()].pop();
}
private:
ThreadId getThreadId() { return /* your system way to get thread id*/; }
std::map<ThreadId, std::stack<Value>> stackPerThread;
};
|
ReentrantReadWriteLock - why can't reader acquire writer's lock?
Date : March 29 2020, 07:55 AM
|