C++ SpinLock 自旋锁的代码实现(全网最简略的方式)

清泛原创
1、最简单的一种,来自《C++并发编程实战》第5章 C++内存模型和原子类型操作:
#include <iostream>
#include <atomic>
#include <thread>
#include <vector>
#include <unistd.h>
using namespace std;

class SpinLock {
	atomic_flag f_;
public:
	SpinLock():f_(ATOMIC_FLAG_INIT) {}
	virtual ~SpinLock() {}
	void lock() { while(f_.test_and_set(memory_order_acquire)); }
	void unlock() { f_.clear(memory_order_release); }
};

2、有退避策略的自旋锁,尝试一定次数(65535)失败后让出线程调度权:
class SpinLockWithYield {
	atomic_flag f_;
public:
	SpinLockWithYield():f_(ATOMIC_FLAG_INIT) {}
	virtual ~SpinLockWithYield() {}
	void lock() {
		unsigned short spinCount = 0;
		while(f_.test_and_set(memory_order_acquire)) {
			if ( (spinCount++) == 0 ) {
#ifdef _WIN32
				SwitchToThread();
#else
				sched_yield();
#endif
			}
		}
	}
	void unlock() { f_.clear(memory_order_release); }
};

3、测试代码如下:
SpinLock lck;

thread thd([&]{
	cout << "thread lock..." << endl;
	lck.lock();
	sleep(3);
	cout << "thread unlock..." << endl;
	lck.unlock();
});
thd.detach();

this_thread::sleep_for(chrono::milliseconds(50));
cout << "main thread lock... wait." << endl;
lck.lock();
cout << "SpinLock done." << endl;
--End--

分享到:
  网友评论(0)
 
回到顶部