STL은 멀티 쓰레드에 안전하지 않습니다.
프로그래밍 2011. 7. 19. 16:35 |STL은 멀티 쓰레드에 안전하지 않습니다.
STL은 여러 쓰레드가 하나의 컨테이너(vector, list, map, string..)을 동시에 사용시 무결성이 깨질수 있는 약점을 가지고 있습니다. 따라서, 사용자는 멀테쓰레드를 사용시에는 컨테이너에 락처리를 손수 해줘야 합니다. 일반적으로 멀티쓰레드에 대한 락처리는 뮤텍스(Mutex), 세마포어(Semaphore), 크리티컬섹션(Critical Secion)을 사용할수 있는데, 여기서는 뮤텍스를 사용해서, 락 처리가 된 클래스를 만들어서 사용해 보겠습니다.
다음 클래스는 앞서 언급한 멀티쓰레드에서 동기화 처리를 위한 간단한 예제입니다.
방식은 생성자에서 락객체(m_hMutex)를 생성하고, lock(), unlock() 함수를 호출하여 락처리를 수행하며, 소멸자에서 생성된 락객체를 삭제합니다.
// Lock.h
#ifndef LOCK_HEADER
#define LOCK_HEADER
class Lock
{
public:
//생성자에서 lock을 생성
Lock() : m_hMutex(NULL)
{
m_hMutex = ::CreateMutex( NULL, false,NULL);
}
//소멸자에서 lock을 소멸
virtual ~Lock()
{
::CloseHandle( m_hMutex );
}
{
if ( m_hMutex == NULL )
return false;
WaitForSingleObject( m_hMutex, INFINITE );
return true;
}
void unlock () //락해제
{
ReleaseMutex(m_hMutex);
}
private:
HANDLE m_hMutex; //lock, unlock에 사용될 객체
};
#endif
이번에는 실제 STL의 컨테이너에 위의 클래스(Lock)를 적용하여 동기화를 구현해 보겠습니다.
// LockVector.h
#ifndef LOCK_VECTOR
#define LOCK_VECTOR
#include "Lock.h"
#include <vector>
using namespace std;
template <class T>
class LockVector : vector<T>, Lock
{
public:
LockVector () : vector<T>(), Lock()
{
}
virtual~ LockVector ()
{
}
void push_back(const T& obj)
{
if (!lock())
return;
vector<T>::push_back (obj);
unlock();
}
#endif
소스에서 보는 것처럼, Lock 클래스와 STL 컨테이너를 다중 상속 받습니다. 이제, 삽입과 삭제에 관련된 메소드는 오버라이딩 해서, 멀티쓰레드 상에서도 안전하게 동작하도록 락처리를 적용 합니다. 여기서는 push_back 함수 하나만 오버라이딩 했지만, 컨테이너내 항목을 삭제하나거 추가하는 함수는 필요시 락처리가 되도록 오버라이딩해서 사용해야 합니다.
다음은 간단한 사용예제 입니다.
// 간단한 LockVector 사용예
#include <iostream>
#include "LockVector.h"
#include <iostream>
int main()
{
LockVector<int> Lv;
Lv.push_back(1);
cout << Lv.at(0) << endl;
return 1;
}
'프로그래밍' 카테고리의 다른 글
SVN: Store password unencrypted (yes/no)? (0) | 2011.07.28 |
---|---|
Visual Assist - Edit Snppet (0) | 2011.07.22 |
스레드 안정성 (0) | 2011.07.19 |
이클립스 color theme (0) | 2011.07.19 |
visual assist 단축키 할당 (0) | 2011.07.19 |