[Qt] QMutex

이번 글에서는 QMutex에 대해 알아보겠습니다.

QMutex는 멀티 쓰레드 상황에서 공유된 자원에 대해 동시에 엑세스 할 때 사용되는 동기화 클래스 입니다.

QMutex를 사용하기 위해서는 아래와 같이 헤더 파일을 include 해야합니다.

#include <QMutex>

QMutex의 사용 방법은 간단합니다.

  • lock: 잠금
  • unlock: 잠금 해제

어떤 상황에서 사용되는지 알아보겠습니다.

Thread의 run 함수에서 ‘특정 작업이 시작되고 종료될 동안 값이 변하지 말아야 하는 변수’가 있어야 한다고 가정해 봅시다.
이 상황을 코드로 표현하면 아래와 같습니다.

void MyThread::run()
{
    m_count = 0;
    m_bThreadStop = false;

    while (!m_bThreadStop)
    {
        // 1. 시작 값 저장
        int iStart = m_count;

        // 2. 특정 작업 ...

        // 3. 종료 값
        int iEnd = m_count;

        // 4. 특정 작업 ...

        // 5. 시작 값과 종료 값이 다르면 에러
        if (iStart != iEnd)
        {
                // 6. 에러 메시지
        }

        // 7. 작업 다 끝나면 1 증가
        m_count++;

        msleep(1000); // 쓰레드 주기 1000msec
    }
}

void MyThread::setCountPlus()
{
    m_count++; // 1 증가
}

위 코드를 보시면 m_count가 시작 값, 종료 값을 가지고 특정 작업을 하게 되어 있고, setCountPlus 함수에서는 m_count를 1증가 시키는 함수로 되어 있습니다.

이 상황에서는 프로그램이 아래와 같이 시작 값과 종료 값이 달라질 수도 있습니다.

만약에 개발자가 시작 값과 종료 값이 달라지지 않게 구현하고 싶다면 QMutex를 사용하시면 간단합니다.

void MyThread::run()
{
    m_count = 0;
    m_bThreadStop = false;

    while (!m_bThreadStop)
    {
        m_mutex.lock();

        // 1. 시작 값 저장
        int iStart = m_count;

        // 2. 특정 작업 ...

        // 3. 종료 값
        int iEnd = m_count;

        // 4. 특정 작업 ...

        // 5. 시작 값과 종료 값이 다르면 에러
        if (iStart != iEnd)
        {
                // 6. 에러 메시지
        }

        m_mutex.unlock();

        // 7. 작업 다 끝나면 1 증가
        m_count++;

        msleep(1000); // 쓰레드 주기 1000msec
    }
}

void MyThread::setCountPlus()
{
    m_mutex.lock();
    m_count++; // 1 증가
    m_mutex.unlock();
}

이렇게 상호 배제를 하고 싶은 부분에 lock, unlock을 하면 됩니다.

이상으로 QMutex에 대해 간단히 알아보았습니다.