旋转锁定堆栈和内存屏障(C)
发布时间:2020-12-16 07:12:47 所属栏目:百科 来源:网络整理
导读:我有一个实现自旋锁: class Spinlock {public: void Lock() { while (true) { if (!_lock.test_and_set(std::memory_order_acquire)) { return; } } } void Unlock() { _lock.clear(std::memory_order_release); }private: std::atomic_flag _lock;}; 我在
我有一个实现自旋锁:
class Spinlock { public: void Lock() { while (true) { if (!_lock.test_and_set(std::memory_order_acquire)) { return; } } } void Unlock() { _lock.clear(std::memory_order_release); } private: std::atomic_flag _lock; }; 我在下面使用SpinLock类: class SpinlockedStack { public: SpinlockedStack() : _head(nullptr) { } ~SpinlockedStack() { while (_head != nullptr) { Node* node = _head->Next; delete _head; _head = node; } } void Push(int value) { _lock.Lock(); _head = new Node(value,_head); _lock.Unlock(); } bool TryPop(int& value) { _lock.Lock(); if (_head == nullptr) { value = NULL; _lock.Unlock(); return false; } Node* node = _head; value = node->Value; _head = node->Next; delete node; _lock.Unlock(); return true; } private: struct Node { int Value; Node* Next; Node(int value,Node* next) : Value(value),Next(next) { } }; Node* _head; Spinlock _lock; }; 我明白我应该设置记忆障碍.我可以使用原子变量: struct Node { int Value; std::atomic<Node*> Next; Node(int value) : Value(value) { } }; std::atomic<Node*> _head; Spinlock _lock; ... void Push(int value) { _lock.Lock(); Node* currentHead = _head.load(std::memory_order_acquire); Node* newHead = new Node(value); newHead->Next.store(currentHead,std::memory_order_relaxed); _head.store(newHead,std::memory_order_release); _lock.Unlock(); } bool TryPop(int& value) { _lock.Lock(); Node* currentHead = _head.load(std::memory_order_acquire); if (currentHead == nullptr) { value = NULL; _lock.Unlock(); return false; } value = currentHead->Value; _head.store(currentHead->Next.load(std::memory_order_relaxed),std::memory_order_release); delete currentHead; _lock.Unlock(); return true; } 我也可以使用atomic_thread_fence(): struct Node { int Value; Node* Next; Node(int value) : Value(value) { } }; Node* _head; Spinlock _lock; ... void Push(int value) { _lock.Lock(); Node* currentHead = _head; std::atomic_thread_fence(std::memory_order_acquire); Node* newHead = new Node(value); newHead->Next = currentHead; std::atomic_thread_fence(std::memory_order_release); _head = newHead; _lock.Unlock(); } bool TryPop(int& value) { _lock.Lock(); std::atomic_thread_fence(std::memory_order_acquire); Node* currentHead = _head; if (currentHead == nullptr) { value = NULL; _lock.Unlock(); return false; } value = currentHead->Value; std::atomic_thread_fence(std::memory_order_acquire); Node* nextNead = currentHead->Next; std::atomic_thread_fence(std::memory_order_release); _head = nextNead; delete currentHead; _lock.Unlock(); return true; } 我的问题: >我是否放置了记忆障碍? 解决方法
获取锁已经确定了您需要的内存保证.
当一个线程释放锁时,它必须写入原子标志.这保证了当下一个线程获得锁并看到对该标志的写入时,获取线程保证在写入该标志之前看到释放线程所做的所有写操作. 在旁注中,您应该使用RAII之类的东西来确保在所有情况下释放锁定. 此外,您必须使用ATOMIC_FLAG_INIT初始化锁定,否则它将处于未定义状态. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |