C ++ concurrent programming: Spinlocks

Spinlocks

definition

Spin lock is when a thread at the time of acquiring the lock, if the lock has been acquired by other threads,
then the thread will wait for the cycle, and then continue to determine whether the lock is successfully acquired, until the lock is acquired will exit the loop.

Spin lock and mutex:

  • Spin lock and mutex is to implement mechanisms to protect shared resources.
  • Whether or spin lock mutex, at any time, you can only have a holder.
  • Acquire the mutex thread, if the lock has been occupied, the thread will go to sleep; get the spin lock thread does not sleep, but has been waiting for the lock release cycle.

Spin lock Summary:

  • When a thread acquires the lock, if the lock is held by another thread, the current thread will loop to wait until the lock is acquired.
  • During spin-lock wait, will not change the state of the thread, the thread has been the state and the user is active (active).
  • If the spin-lock holds the lock for too long, it will lead to other threads waiting to acquire a lock depletion CPU.
  • Spin lock itself can not guarantee fairness, but can not guarantee reentrancy.
  • Based on the spin locks may be provided to achieve fairness and reentrant lock properties

Other kinds of locks for different scenarios:

  • If a multi-core processor, a thread if the expected wait time locks very short to twice the thread context switching than the case where less time using a spin lock is cost-effective.
  • If the multi-core processor, if the expected wait time thread locks longer than at least twice the thread context switching time is longer, it is recommended to use mutex.
  • If the single-core processor, generally we do not recommend using spin locks. Because, at the same time only one thread is running in the state, and that if found it impossible to get running thread lock, unlock can only wait, but not because of their pending, so that the thread acquired the lock is no way to enter the running state, only wait until the operating system running thread and give it time slice runs out, in order to have the opportunity to be scheduled. Use high spin lock in this case the price.
  • If the lock code can be called often, but when the competition rarely happens, should give priority to the use of spin lock spin lock overhead is relatively small, mutex large overhead.

to sum up:

  • Non-essential, try not to use spin locks (difficult to achieve a reasonable and efficient spin lock)
  • The same thread twice lock (), is likely to deadlock.

Simple examples of spin locks

#include "pch.h"
#include <iostream>
#include <atomic>
#include <thread>
#include <chrono>

using namespace std;

class SpinLock {
public:	
	inline void Lock() {
		while (m_flag.test_and_set()) {
			std::this_thread::yield();
		}
	}
	inline void UnLock() { m_flag.clear(); }
private:
	std::atomic_flag m_flag = ATOMIC_FLAG_INIT;
};

void fun1(int i,SpinLock& lock) {
	while (1) {
		lock.Lock();
		std::cout << "threadId:" << i << ":starting" << std::endl;
		std::this_thread::sleep_for(std::chrono::microseconds(100));
		lock.UnLock();
	}
	
}

void fun2(int i,SpinLock& lock) {
	while (1) {
		lock.Lock();
		std::cout << "threadId:" << i << ":starting" << std::endl;
		std::this_thread::sleep_for(std::chrono::milliseconds(100));
		lock.UnLock();
	}
}

int main()
{
	SpinLock lock;
	std::thread t1(fun1,1,std::ref(lock));
	std::thread t2(fun2, 2, std::ref(lock));
	t1.join();
	t2.join();
	return 0;
}
Published 155 original articles · won praise 15 · views 160 000 +

Guess you like

Origin blog.csdn.net/wangdamingll/article/details/104432321