女性手表网站,开发网站做图文水印逻辑,WordPress通讯目录,a站网址是什么本文使用内存屏障来 VolatileRead、VolatileWrite 保证读写重入自旋锁的当前线程ID#xff08;tid#xff09;#xff0c;如果不愿意采用内存屏障的方式来处理#xff0c;人们可以选择使用原子变量读写来代替。
C 置R/W内存屏障#xff1a; static inline void Mem…本文使用内存屏障来 VolatileRead、VolatileWrite 保证读写重入自旋锁的当前线程IDtid如果不愿意采用内存屏障的方式来处理人们可以选择使用原子变量读写来代替。
C 置R/W内存屏障 static inline void MemoryBarrier() noexcept{std::atomic_thread_fence(std::memory_order_seq_cst);}
头文件
#pragma once#include ppp/stdafx.hnamespace ppp
{namespace threading{class SpinLock final{public:explicit SpinLock() noexcept;SpinLock(const SpinLock) delete;SpinLock(SpinLock) delete;~SpinLock() noexcept(false);public:SpinLock operator(const SpinLock) delete;public:bool TryEnter() noexcept;bool TryEnter(int loop, int timeout) noexcept;void Enter() noexcept;void Leave();inline bool IsLockTaken() noexcept { return _.load(); }public:inline void lock() noexcept { Enter(); }inline void unlock() noexcept { Leave(); }public:std::atomicbool _;};class RecursiveSpinLock final{public:explicit RecursiveSpinLock() noexcept;RecursiveSpinLock(const RecursiveSpinLock) delete;RecursiveSpinLock(RecursiveSpinLock) delete;~RecursiveSpinLock() default;public:RecursiveSpinLock operator(const RecursiveSpinLock) delete;public:bool TryEnter() noexcept;bool TryEnter(int loop, int timeout) noexcept;void Enter() noexcept;void Leave();inline bool IsLockTaken() noexcept { return lockobj_.IsLockTaken(); }public:inline void lock() noexcept { Enter(); }inline void unlock() noexcept { Leave(); }public:SpinLock lockobj_;volatile int tid_;std::atomicint reentries_;};}
}
源文件
#include ppp/threading/SpinLock.h
#include ppp/threading/Thread.hnamespace ppp
{namespace threading{template class LockObjectstatic constexpr bool Lock_TryEnter(LockObject lock, int loop,int timeout) noexcept{bool lockTaken false;if (loop -1){uint64_t last GetTickCount();for (int i 0; i loop; i){lockTaken lock.TryEnter();if (lockTaken){break;}if (timeout -1){uint64_t now GetTickCount();int64_t diff now - last;if (diff timeout){break;}}}}else{uint64_t last GetTickCount();for (;;){lockTaken lock.TryEnter();if (lockTaken){break;}if (timeout -1){uint64_t now GetTickCount();int64_t diff now - last;if (diff timeout){break;}}}}return lockTaken;}template class LockObject, class LockInternalObject, typename... TryEnterArgumentsstatic constexpr bool RecursiveLock_TryEnter(LockObject lock, LockInternalObject lock_internal, volatile int* tid,std::atomicint reentries, TryEnterArguments... arguments){int n reentries;assert(n 0);int current_tid std::hashstd::thread::id{}(std::this_thread::get_id());if (n 1){bool lockTaken lock_internal.TryEnter(std::forwardTryEnterArguments(arguments)...);if (!lockTaken){reentries--;return false;}Thread::MemoryBarrier();*tid current_tid;Thread::MemoryBarrier();}else{Thread::MemoryBarrier();int lockTaken_tid *tid;Thread::MemoryBarrier();if (lockTaken_tid current_tid){lock.Leave();return false;}}return true;}SpinLock::SpinLock() noexcept: _(false){}SpinLock::~SpinLock() noexcept(false){bool lockTaken IsLockTaken();if (lockTaken){throw std::runtime_error(fail to release the atomic lock.);}}void SpinLock::Enter() noexcept{for (;;) {bool lockTaken TryEnter();if (lockTaken){break;}}}bool SpinLock::TryEnter(int loop, int timeout) noexcept{return Lock_TryEnter(*this, loop, timeout);}bool SpinLock::TryEnter() noexcept{bool expected false;return _.compare_exchange_strong(expected, true, std::memory_order_acquire);}void SpinLock::Leave(){bool expected true;if (!_.compare_exchange_strong(expected, false, std::memory_order_release)){throw std::runtime_error(failed to acquire the atomic lock.);}}RecursiveSpinLock::RecursiveSpinLock() noexcept: lockobj_(), tid_(0), reentries_(0){}bool RecursiveSpinLock::TryEnter() noexcept{return RecursiveLock_TryEnter(*this, lockobj_, tid_, reentries_);}bool RecursiveSpinLock::TryEnter(int loop, int timeout) noexcept{return RecursiveLock_TryEnter(*this, lockobj_, tid_, reentries_, loop, timeout);}void RecursiveSpinLock::Enter() noexcept{for (;;){bool lockTaken TryEnter();if (lockTaken){break;}}}void RecursiveSpinLock::Leave() {int n --reentries_;assert(n 0);if (n 0){lockobj_.Leave();}}}
}