반응형

- 본 내용은 Linux (Ubuntu 14.04 lts)를 기반으로 제작되었습니다. -



Mutual Exclusion object - Mutex(뮤텍스)


스레드들 간에서 공유가 배제되는 객체. 


파일과 같은 공유 자원이 수행 중 오직 한 프로그램이나 스레드에게만 소유되어야 할 필요가 있을 

그 자원에 대한 뮤텍스 객체를 생성시킨다. 


뮤텍스가 비신호 상태이면 프로그램은 자원을 점유하여 사용한 후 이를 반환하고, 

다른 프로그램 또는 다른 스레드가 자원을 사용 중 즉, 뮤텍스가 신호 상태이면 대기 상태로 들어가 끝나기를 기다린다. 


뮤텍스는 여러 면에서 크리티컬 섹션과 비슷하고, 대신 사용할 수도 있지만 

이름을 가질 수 있다는 점에서 크리티컬 섹션보다 우월하다.


(출처 : http://terms.naver.com/entry.nhn?docId=864468&cid=42346&categoryId=42346)


예를 들면 다음과 같다.


뮤텍스는 1인 화장실을 들어가기 위한 열쇠와 같다.


무슨 의미냐면 화장실에 들어가기위해 열쇠를 가진 사람만이 화장실에 들어갈 수 있다.


화장실에 들어가있다면 다른 사람들은 그 사람이 열쇠를 주기를 기다려야한다.(이것을 대기 큐 라고한다.)


볼일이 끝나면 다음 사람이 열쇠를 받게 되는 방식이다.



특징


- 하나의 스레드만 크리티컬 섹션에 들어갈 수 있다.


즉, 그 영역에 하나의 스레드가 있다면 들어갈 수 없다.


- 뮤텍스를 생성하고 난 뒤 파괴하고 싶다면, 반드시 뮤텍스를 unlock 하고 파괴해야한다.







예제 코드


threadID1,2는 뮤텍스를 이용하고, threadID3,4는 뮤텍스를 이용하지 않는다.


(threadID3,4에 대한 내용은 http://www.crocus.co.kr/485 에서 참조 할 수 있다.)


뮤텍스를 통해 락을 걸고 풀게되면, 락 ~ 언락 부분을 모두 수행할 때 까지 다른 스레드가 수행이 되지 않고


wait상태로 있는다.


즉, 컨텍스트 스위칭은 일어날지라도, thread1이 계속 작업하고 있었더라면, thread2는 가만히 기다리다


다시 컨텍스트 스위칭을 당하게 된다. 


결과를 보면 sum은 2000000으로 정확히 계속 나오지만, sum1은 뒤죽박죽임을 알 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Using Mutex
 
#include <pthread.h>
#include <stdio.h>
 
pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER;
 
int sum = 0;
int sum1 = 0;
 
void *threadRoutine(void *argumentPointer)
{
    int i;
 
    // 뮤텍스 락을 거는 과정
    pthread_mutex_lock(&counter_mutex);
 
    // 이 부분이 Critical Section에 해당한다.
    for(i = 0; i < 1000000; i ++)
        sum++;
 
    // 뮤텍스 락을 푸는 과정
    pthread_mutex_unlock(&counter_mutex);
    
    return NULL;
}
 
void *threadRoutine1(void *argumentPointer)
{
    int i;
 
    // 이 부분이 Critical Section에 해당한다.
    for(i = 0; i < 1000000; i ++)
        sum1++;
 
    return NULL;
}
 
int main()
{
    pthread_t threadID1, threadID2;
    pthread_t threadID3, threadID4;
 
    // Create < 뮤텍스 이용 >
    pthread_create(&threadID1, NULL, threadRoutine, NULL);
    pthread_create(&threadID2, NULL, threadRoutine, NULL);
 
    // Create < 뮤텍스 이용 x >
    pthread_create(&threadID3, NULL, threadRoutine1, NULL);
    pthread_create(&threadID4, NULL, threadRoutine1, NULL);
 
    // Join < 뮤텍스 이용 >
    pthread_join(threadID1, NULL);
    pthread_join(threadID2, NULL);
 
    // Join < 뮤텍스 이용 x >
    pthread_join(threadID3, NULL);
    pthread_join(threadID4, NULL);
 
    printf("뮤텍스를 이용한 결과 합 :: %d\n",sum);
    printf("뮤텍스를 이용하지 않은 결과 합 :: %d\n",sum1);
 
    return 0;
}
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus




















반응형