标签:default appear atomic roc ESS smp ade 防止 evel
reference:
原子操作、内存屏障、锁:https://www.jianshu.com/p/1d90fe6627ad
哪些操作本身是原子的?
c++版读写锁 https://blog.csdn.net/zxc024000/article/details/88814461
volatile
谈谈C/C++中的volatile:https://zhuanlan.zhihu.com/p/33074506
内存模型:https://cloud.tencent.com/developer/article/1479199
volatile object - an object whose type is volatile-qualified, or a subobject of a volatile object, or a mutable subobject of a const-volatile object. Every access (read or write operation, member function call, etc.) made through a glvalue expression of volatile-qualified type is treated as a visible side-effect for the purposes of optimization (that is, within a single thread of execution, volatile accesses cannot be optimized out or reordered with another visible side effect that is sequenced-before or sequenced-after the volatile access. This makes volatile objects suitable for communication with a signal handler, but not with another thread of execution, see std::memory_order). Any attempt to refer to a volatile object through a non-volatile glvalue (e.g. through a reference or pointer to non-volatile type) results in undefined behavior.
C/C++ and "volatile"
When writing single-threaded code, declaring a variable “volatile” can be very useful. The compiler will not omit or reorder accesses to volatile locations. Combine that with the sequential consistency provided by the hardware, and you’re guaranteed that the loads and stores will appear to happen in the expected order.
However, accesses to volatile storage may be reordered with non-volatile accesses, so you have to be careful in multi-threaded uniprocessor environments (explicit compiler reorder barriers may be required). There are no atomicity guarantees, and no memory barrier provisions, so “volatile” doesn’t help you at all in multi-threaded SMP environments. The C and C++ language standards are being updated to address this with built-in atomic operations.
If you think you need to declare something “volatile”, that is a strong indicator that you should be using one of the atomic operations instead.
Java版读写锁(来自打驰哥) https://www.cnblogs.com/DarrenChan/p/8619476.html
防止写者饿死精要:
写者到来的时候,先m_writeCount++,再判断是否读者为0,并且未出于写的过程中;(直接判断m_writeCount == 1是否可行?)
读者到来的时候,先检查m_writeCount
#ifndef RWLOCK__H
#define RWLOCK__H
#ifndef __cplusplus
# error ERROR: This file requires C++ compilation(use a .cpp suffix)
#endif
#include <mutex>
#include <condition_variable>
namespace linduo {
class RWLock {
public:
RWLock();
virtual ~RWLock() = default;
void lockWrite();
void unlockWrite();
void lockRead();
void unlockRead();
private:
volatile int m_readCount;
volatile int m_writeCount;
volatile bool m_isWriting;
std::mutex m_Lock;
std::condition_variable m_readCond;
std::condition_variable m_writeCond;
};
class ReadGuard {
public:
explicit ReadGuard(RWLock& lock);
virtual ~ReadGuard();
private:
ReadGuard(const ReadGuard&);
ReadGuard& operator=(const ReadGuard&);
private:
RWLock &m_lock;
};
class WriteGuard {
public:
explicit WriteGuard(RWLock& lock);
virtual ~WriteGuard();
private:
WriteGuard(const WriteGuard&);
WriteGuard& operator=(const WriteGuard&);
private:
RWLock& m_lock;
};
} /* namespace linduo */
#endif // RWLOCK__H
#include "RWLock.h"
namespace linduo {
RWLock::RWLock()
: m_readCount(0)
, m_writeCount(0)
, m_isWriting(false) {
}
void RWLock::lockRead() {
std::unique_lock<std::mutex> gurad(m_Lock);
m_readCond.wait(gurad, [=] { return 0 == m_writeCount; });
++m_readCount;
}
void RWLock::unlockRead() {
std::unique_lock<std::mutex> gurad(m_Lock);
if (0 == (--m_readCount)
&& m_writeCount > 0) {
// One write can go on
m_writeCond.notify_one();
}
}
void RWLock::lockWrite() {
std::unique_lock<std::mutex> gurad(m_Lock);
++m_writeCount;
m_writeCond.wait(gurad, [=] { return (0 == m_readCount) && !m_isWriting; });
m_isWriting = true;
}
void RWLock::unlockWrite() {
std::unique_lock<std::mutex> gurad(m_Lock);
m_isWriting = false;
if (0 == (--m_writeCount)) {
// All read can go on
m_readCond.notify_all();
} else {
// One write can go on
m_writeCond.notify_one();
}
}
ReadGuard::ReadGuard(RWLock &lock)
: m_lock(lock) {
m_lock.lockRead();
}
ReadGuard::~ReadGuard() {
m_lock.unlockRead();
}
WriteGuard::WriteGuard(RWLock &lock)
: m_lock(lock) {
m_lock.lockWrite();
}
WriteGuard::~WriteGuard() {
m_lock.unlockWrite();
}
} /* namespace linduo */
RWLock m_Lock;
void Wfunc() {
// 写锁
WriteGuard autoSync(m_Lock);
}
void Rfunc() {
// 读锁
ReadGuard autoSync(m_Lock);
}
标签:default appear atomic roc ESS smp ade 防止 evel
原文地址:https://www.cnblogs.com/dirge/p/11874856.html