SpinLock source code

1. Summary

The basic principle of spinLock is that if you find that someone else is locked, it keeps looping, and then locks it after knowing that someone else has unlocked it. Generally, SpinLock is suitable for the situation where the lock time is very short. By constantly determining whether the lock can be locked, it is avoided that the application of Mutex and other operating system locks brings about context switching when the lock cannot be locked.

Second, realize the source code

#pragma once
#include <atomic>
#include <thread>
using namespace std;
class SpinLock
{
    
    
private:
	atomic<bool> _flag;
public:
	SpinLock()
	{
    
    
		_flag = false;
	}
	void lock()
	{
    
    
		bool r = false;
		while (!_flag.compare_exchange_strong(r, true)) //如果_flag为false,就把_flag改为true,r改为false,并且保证_flag的获取和修改时原子的
		{
    
    
			r = false;
		}
	}
	void unlock()
	{
    
    
		_flag.store(false);
	}
};
class SpinLockTest
{
    
    
private:
	int count = 0;
	int spinCount = 0;
	int maxLoop = 10000000;
	SpinLock lock;
public:

	void doTest()
	{
    
    
		thread thread1([this](){
    
    this->process(); });
		thread thread2([this](){
    
    this->process(); });
		thread1.join();
		thread2.join();

		thread thread3([this]() {
    
    this->spinProcess(); });
		thread thread4([this]() {
    
    this->spinProcess(); });
		thread3.join();
		thread4.join();
		printf("count=%d spinCount=%d\n", count, spinCount);
		
	}
	void process()
	{
    
    
		for (int i = 0; i < maxLoop; i++)
		{
    
    
			count++;
		}
	}
	void spinProcess()
	{
    
    
		for (int i = 0; i < maxLoop; i++)
		{
    
    
			lock.lock();
			spinCount++;
			lock.unlock();
		}
	}
};

Three, output results

count=13795495 spinCount=20000000

Three, code analysis

  • It can be seen from the result that spinLock realizes the atomic operation of spinCount, while ordinary multi-threaded accumulation cannot guarantee atomicity.
  • Atomic is used. Atomic can realize atomic read, atomic write and CAS operations of basic types of data. CAS is a comparison exchange. When the current value is the same as the expected value, it is exchanged for the target value. This involves reading and writing of Atomic values. Atomic read and write alone cannot guarantee that the entire read and write is atomic. Fortunately, Atomic provides CAS operations. CAS realizes atomic reading and writing of data through CPU-level lock-free operations without causing context switching. It has several times the performance improvement compared to Mutex operating system-level locks.

Guess you like

Origin blog.csdn.net/gamekit/article/details/107294109