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

deadlock

by bongin 2024. 11. 26.
728x90
반응형

* t1 : m1->m2, t2 : m1->m2

#include <iostream>
using namespace std;
#include <thread>
#include <vector>
#include <Windows.h>
#include <atomic>
#include <mutex>
#include <map>

mutex m1;
mutex m2;

template<typename T>
class Lock_Guard
{
public:
    Lock_Guard(T& m) : _mutex(m)
    {
        cout << "① 생성, t : " << this_thread::get_id() << ", m : " << &_mutex << endl;
        _mutex.lock();
        cout << "잠금" << endl;
    }
    ~Lock_Guard()
    {
        cout << "③ 파괴 : " << this_thread::get_id() << endl;
        _mutex.unlock();
        cout << "해금" << endl;
    }
private:
    T& _mutex;
};

void star()
{
    for (int i = 0; i < 5; i++)
    {
        Lock_Guard<mutex> lockGuard1(m1);
        cout << "② m1 실행 : " << this_thread::get_id() << endl;
        Lock_Guard<mutex> lockGuard2(m2);
        cout << "② m2 실행 : " << this_thread::get_id() << endl;
    }
}

void sun()
{
    for (int i = 0; i < 5; i++)
    {
        Lock_Guard<mutex> lockGuard1(m1);
        cout << "② m1 실행 : " << this_thread::get_id() << endl;
        Lock_Guard<mutex> lockGuard2(m2);
        cout << "② m2 실행 : " << this_thread::get_id() << endl;
    }
}

int main()
{
    thread t1(star);
    thread t2(sun);

    t1.join();
    t2.join();

    std::cout << "실행 완료" << endl;
}

-> 정상 실행, 결과 :

 

(time table)

 

 

 

* t1 : m1->m2, t2 : m2->m1

#include <iostream>
using namespace std;
#include <thread>
#include <vector>
#include <Windows.h>
#include <atomic>
#include <mutex>
#include <map>

mutex m1;
mutex m2;

template<typename T>
class Lock_Guard
{
public:
    Lock_Guard(T& m) : _mutex(m)
    {
        cout << "① 생성, t : " << this_thread::get_id() << ", m : " << &_mutex << endl;
        _mutex.lock();
        cout << "잠금" << endl;
    }
    ~Lock_Guard()
    {
        cout << "③ 파괴 : " << this_thread::get_id() << endl;
        _mutex.unlock();
        cout << "해금" << endl;
    }
private:
    T& _mutex;
};

void star()
{
    for (int i = 0; i < 5; i++)
    {
        Lock_Guard<mutex> lockGuard1(m1);
        cout << "② m1 실행 : " << this_thread::get_id() << endl;
        Lock_Guard<mutex> lockGuard2(m2);
        cout << "② m2 실행 : " << this_thread::get_id() << endl;
    }
}

void sun()
{
    for (int i = 0; i < 5; i++)
    {
        Lock_Guard<mutex> lockGuard2(m2);
        cout << "② m2 실행 : " << this_thread::get_id() << endl;
        Lock_Guard<mutex> lockGuard1(m1);
        cout << "② m1 실행 : " << this_thread::get_id() << endl;
    }
}

int main()
{
    thread t1(star);
    thread t2(sun);

    t1.join();
    t2.join();

    std::cout << "실행 완료" << endl;
}

-> 멈춤, 결과 :

 

(time table)

 

t1 : m1 -> m2 ->

t2 : 대기   대기   m1 -> m2

일 때는 문제가 없으나,

 

t1 : m1 -> m2 (t2의 m2가 해금되야 t1의 m2 잠금 가능)

t2 : m2 -> m1 (t1의 m1이 해금되야 t2의 m1 잠금 가능)

일 때 문제 발생, 루프를 끝내고 나가는 시점에 해금이 되므로 t1, t2 모두 잠금 대기 상태로 무한 루프에 갇힘

 

 

728x90
반응형

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

spin lock  (0) 2024.11.19
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

댓글