[C] pthread_mutex 이해하기

두비니

·

2021. 5. 7. 13:40

 

 

 

 

 

 

thread에서 가장 중요한 이슈는 race condition입니다. 동일한 메모리에 접근할 때, 그 메모리에 대해서 일관성이 유지될수 있는가?에대한 문제죠.

 

이런걸 해결하기 위해서 대표적으로 사용할 수 있는 함수가 pthread_mutex입니다. 오늘은 그 함수를 어떻게 사용해야하는지에 대해서 보도록 하겠습니다.

 

 

01. 문제상황 이해

 

우선 문제가 있는 상황을 통해서 이해를 해봅시다. 다음은 간단한 thread를 통한 코드입니다

 

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

int mails = 0;

void* routine(){
	for (int i=0;i<1000000;i++){
		mails++;
	}
}

int main(){
	pthread_t p1, p2;
	if (pthread_create(&p1, NULL, &routine, NULL) != 0)
		return 1;
	if (pthread_create(&p2, NULL, &routine, NULL) != 0)
		return 2;

	if (pthread_join(p1, NULL) != 0)
		return 3;
	if (pthread_join(p2, NULL) != 0)
		return 4;
	printf("Number of mails : %d\n", mails); 
	return 0;
}

 

단순히 thread를 2개 만들어서 동일한 전역변수에 도달하게 하는 코드입니다.

 

 

위 캡쳐처럼 항상 일어나진 않아도 종종 race condition이 발생하는 것을 볼 수 있습니다.

 

 

02. pthread_mutex 사용방법

 

우선 결론 코드입니다.

 

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

int mails = 0;
pthread_mutex_t mutex;

void* routine(){
	for (int i=0;i<1000000;i++){
		pthread_mutex_lock(&mutex);
		mails++;
		pthread_mutex_unlock(&mutex);
	}
}

int main(){
	pthread_t p1, p2;
	pthread_mutex_init(&mutex, NULL);
	if (pthread_create(&p1, NULL, &routine, NULL) != 0)
		return 1;
	if (pthread_create(&p2, NULL, &routine, NULL) != 0)
		return 2;

	if (pthread_join(p1, NULL) != 0)
		return 3;
	if (pthread_join(p2, NULL) != 0)
		return 4;


	pthread_mutex_destroy(&mutex, NULL);
	printf("Number of mails : %d\n", mails); 
	return 0;
}

 

추가된 부분을 하나하나 보도록 합시다.

 

pthread_mutex_t mutex;

 

우선 이 mutex라는 것을 선언을 미리 해주어야 합니다.

 

	pthread_mutex_init(&mutex, NULL);
	pthread_mutex_destroy(&mutex, NULL);

 

그리고, 각각 mutex_init과 mutex_destroy라는 함수로 기본적인 설정을 해줍니다. thread에서 thread_create와 thread_join/exit같은걸 하는 것과 동일한 맥락입니다.

 

 

		pthread_mutex_lock(&mutex);
		pthread_mutex_unlock(&mutex);

 

그리고 routine 실행 함수 안을 보면 각각 mutex_lock과 mutex_unlock이 작성되어있는 걸 볼 수 있습니다.

이건 아래 오토마타로 표현할 수 있습니다.

 

 

근데 별건 아니고, race condition처럼 누구나 다같이 달려들 수 있는 상황이 아니라, 딱 unlock된 상황에서만 코드 실행을 허용한다고 보면 될 것 같습니다. 재밌네용

 

 

아 결과값은 다음과 같이 나옵니다. 아무리 많이 돌려도 race condition이 일어나지 않을 것을 알 수 있습니다.

 

 

참고자료 : www.youtube.com/watch?v=oq29KUy29iQ