이번 글에서는 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에 대해 간단히 알아보았습니다.