×
Crocus
공부한 내용을 정리하는 블로그로 시작한
Crocus는 2014년 1월 14일 부터 시작하여
현재 월 6만명, 총 1,205,939명의 방문자 수를 기록하고 있습니다.
Donation
이제 많은 사용자들이 이용하는 만큼
더 다양한 서비스 개발/제공을 위해 후원금을 모금하고자 합니다.
후원을 해주시는 분들은 Donators 명단에 성명, 후원금을 기입해드리며
Crocus 블로그가 아닌 다른 곳에 정리해둔 저만의 내용을 공유해 드리고자 합니다.
Account
예금주 : 고관우
신한은행 : 110-334-866541
카카오뱅크 : 3333-01-7888060

👉 후원 페이지 바로가기 Donators
익명 : 5000원(Crocus응원합니다.)

- 본 내용은 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