본문 바로가기
코드/C++

spin lock

by bongin 2024. 11. 19.
728x90
반응형
#include <iostream>
using namespace std;
#include <thread>
#include <vector>
#include <Windows.h>
#include <atomic>
#include <mutex>

class Lock
{
public:
    void lock()
    {
        while (_flag)
        {
            //_flag == true일 때 아래로 못내려 감
        }
        
        _flag = true;//_flag == false가 되자마자 true로 바꿔 다른 스레드가 못쓰게 함
    }

    void unlock()
    {
        _flag = false;
    }

private:
  atomic<bool> _flag = false;
};

Lock m;
vector<int> v;

void Push()
{
    for (int i = 0; i < 10000; i++)
    {
        std::lock_guard<Lock> lockGuard(m);

        v.push_back(i);

        if (i == 5000)
        {
            break;
        }
    }
}

int main()
{
    v.reserve(100000);

    thread t1(Push);
    thread t2(Push);
    
    t1.join();
    t2.join();

    std::cout << v.size() << std::endl;
}

-> 출력 : 9997 (_flag = true를 두 쓰레드가 동시에 실행하여 씹힘)

    void lock()
    {
            while (_flag)
            {
                //_flag == true일 때 아래로 못내려 감, _flag가 false일 때 탈출함
            }
        
            //_flag == false가 되자마자 true로 바꿔 다른 스레드가 못쓰게 함
            _flag = true;
    }

 

 

위처럼 _flag가 false가 될 때 쓰레드 두개가 동시에 _flag를 true로 만드는 문제가 있음

이를 해결하기 위해 CPU 레벨에서 아래 과정을 순차적이 아니라 한번에 처리 함

bool expected = false;
bool desired = true;



if (_flag == expected ( = false))
{
        _flag = desired ( = true);
        //_flag == false가 되자마자 true로 바꿔 다른 스레드가 못쓰게 함

        return true; //성공했는지 실패했는지를 알려 줌
}
else
{
        expected = _flag ( = false);
        return false;
}

compare_exchange_strong함수의 첫 번째 파라미터는 레퍼런스로 받기 때문에 값이 계속해서 변하게 된다. 그렇기 때문에 초기 값으로 계속해서 초기화를 해줘야 정상적으로 작동한다. 이해하기 어렵다면 맨 아래의 compare_exchange_strong의 의사코드를 먼저 보는 것을 추천한다.

https://m.blog.naver.com/han931120/223565699718

 

이를 compare_exchange_strong로 표현하면

void lock()
{
    bool expected = false;
    bool desired = true;

    _flag.compare_exchange_strong(expected, desired);
    while (_flag.compare_exchange_strong(OUT expected, desired) == false)
    {
        expected = false;
    }
}

 

728x90
반응형

'코드 > C++' 카테고리의 다른 글

deadlock  (0) 2024.11.26
Lock  (0) 2024.11.12
PE File Format, notepad  (0) 2024.06.10
release 배포 시 dll 오류 날 때  (2) 2023.11.21
std::to_wstring(int), _tow_s(int, wchar_t, 2 or 10);  (0) 2023.11.16

댓글