|  |  |
|
다중 스레드 메모리 관리자
지금까지는 병렬 환경을 고려하지 않고 메모리 관리자를 설계했다. 다중 스레드 환경에서는 여러
스레드가 동시에 메모리를 할당하고 해제할 위험이 존재한다. 그러므로 다중 스레드 환경에서는
메모리 관리자가 수행하는 메모리 할당/해제 연산이 원자적(atomic)이어야 한다. 다시
말하면, 두 스레드가 동시에 메모리 연산을 시도해도 메모리 관리자는 상호 배타성을 보장해야
한다는 뜻이다. 할당/해제를 원자적 연산으로 만드는 표준 방법 중 하나가 잠금(lock)
메커니즘이다. 메모리를 할당하거나 해제하려는 스레드는 먼저 하나뿐인 잠금을 소유해야 한다.
다른 스레드가 이미 잠금을 소유하고 있다면, 현재 스레드는 대기 상태(block)로 들어간다.
Listing 21
은 잠금 방식을 사용하는 함수 서식을 보여준다.
Listing 21. pthread mutex 메서드
#include <pthread.h>
int pthread_mutex_init(pthread_mutex_t *mutex,
const pthread_mutexattr_t *attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
|
우리 목적에 맞추려면 잠금과 잠금 해제를 흉내내기 위해 GNU 컴파일러가 제공하는 잠금
메커니즘만으로 충분하다. pthread mutex는 표준 헤더인
pthread.h
에 정의되어 있다.
allocation
/
free
코드는
pthread_mutex_lock
과
pthread_mutex_unlock
메서드 사이에 놓인다. 한 스레드가 메모리 풀을 참조하는 동안에 다른 스레드가 pthread
메서드를 호출하면 잠금이 해제될 때까지 기다리게 된다.
Listing 22
는 코드를 수정한 모습이다.
Listing 22. allocation/free 메서드를 수정한 모습
void* MemoryManager::allocate(size_t size)
{
pthread_mutex_lock (&lock);
... // usual memory allocation code
pthread_mutex_unlock (&lock);
}
void* MemoryManager::free(size_t size)
{
pthread_mutex_lock (&lock);
... // usual memory deallocation code
pthread_mutex_unlock (&lock);
} |
이제 메모리 관리자 클래스에
pthread_mutex_lock
객체를 포함시킨다. 클래스 생성자를 적절히 변경해서
pthread_mutex_init
을 호출하여 잠금을 초기화한다. 마찬가지로, 메모리 관리자 소멸자는
pthread_mutex_destroy
를 호출하여 mutex 객체를 소멸한다.
Listing 23
은
MemoryManager
클래스를 수정한 모습이다.
Listing 23. 다중 스레드 할당/할당 해제를 처리하는 MemoryManager
클래스
class MemoryManager : public IMemoryManager
{
pthread_mutex_t lock;
... // usual MemoryManager code follows
};
MemoryManager::MemoryManager ()
{
pthread_mutex_init (&lock, NULL);
... // usual constructor code
}
MemoryManager:: ~MemoryManager ()
{
... // usual destructor code
pthread_mutex_destroy (&lock);
}
|
이제 다중 스레드 환경에서 메모리 관리자를 돌려 보자. 우리 테스트에서는 단일 스레드 환경보다
속력이 확실히 떨어졌다. 상황에 맞게 구현한 특수 메모리 관리자가 필요한 이유가 다시 한 번
드러난다.
|  |
|