반응형

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





목록

1. Producer and Consumer

2. Mutex Condition

3. Mutex Condition Producer and Consumer






1. Producer and Consumer


흔히 세마포어, 뮤텍스를 학습하다 보면 프로듀서 컨슈머라는 대표적인 예제를 통해 대해 알아보곤 한다.


왜 Producer and Consumer을 이용하나?


프로듀서 컨슈머는 하나의 Buffer을 공유한다.


우리가 뮤텍스, 세마포어를 배우는 이유도 Unsafe Region을 동기화된 지역으로 (Critical Section으로 만들어서)


변경시켜 코드상의 문제 및 실행상의 문제를 해결하기 위함이다.


이번에 알아볼 프로듀서 컨슈머의 예제 코드가 돌아가는 방식은 다음과 같다.


0. 초기 프로듀서의 세마포어는 1개로 시작하고, 컨슈머의 세마포어는 0개로 시작한다.


1. 생산된 아이템이 0개라면 프로듀서는 프로듀서의 세마포어를 P를 통해 소비하여 제작에 들어간다.


2. 프로듀서가 생산을 마치면 프로듀서의 세마포어를 V를 통해 1개 늘리는 것이 아닌,

컨슈머의 V를 통해 1개를 늘려 컨슈머가 깨어나도록 한다.


3. 다음 프로듀서가 다시 아이템을 생산하려해도 이미 프로듀서의 세마포어가 0개이므로,

생산을 하러 갈 수 없고, sleep상태에 접어든다. 


4. 이때 컨슈머는 세마포어의 수가 0개에서 1개가 되었으니, 아이템을 소비한다.

그리고 나서 컨슈머의 V를 해주는 것이 아닌 프로듀서의 V를 해줌으로써 아이템을 생산 할 수 있도록한다.





세마포어(Semaphore)를 이용한 Producer and Consumer


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
67
68
69
70
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
 
// Producer 세마포어, Consumer 세마포어 선언
sem_t P,C; 
int item;
 
void* threadFuncP(void* arg)
{
    int i;
    
    for (i = 0; i < 100; i++)
    {
        // Producer에 P기능을 수행
        sem_wait(&P);
        
        // Critical Section
        item = i;
        printf("Producer에서 아이템 생산 :: %d\n",item);
 
        // Consumer에 V기능을 수행
        sem_post(&C);
    }
 
    return 0;
}
 
void* threadFuncC(void* arg)
{
    int i, get;
 
    for (i = 0; i < 100; i++)
    {
        // Consumer에 P기능을 수행
        sem_wait(&C);
 
        // Critical Section
        get = item;
        printf("Consumer에서 아이템 소비 :: %d\n",get);
 
        // Producer에 V기능을 수행
        sem_post(&P);
    }
 
    return 0;
}
 
int main()
{
    // Producer, Consumer 스레드 선언
    pthread_t threadP, threadC;
 
    // 세마포어 초기화(Producer 세마포어 :: 1, Consumer 세마포어 :: 0)
    sem_init(&P, 01);
    sem_init(&C, 00);
 
    // 스레드 생성
    pthread_create(&threadP, NULL, threadFuncP, NULL);
    pthread_create(&threadC, NULL, threadFuncC, NULL);
 
    // 스레드 조인
    pthread_join(threadP, NULL);
    pthread_join(threadC, NULL);
 
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus










3. 뮤텍스(Mutex)를 이용한 Producer and Consumer


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
#include <stdio.h>
#include <pthread.h>
 
 
// 프로듀서 컨슈머 뮤텍스 선언
pthread_mutex_t mutexP = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutexC = PTHREAD_MUTEX_INITIALIZER;
 
int item;
 
void *threadFuncP(void* arg)
{
    int i;
 
    for(i = ; i < 100; i ++)
    {
        pthread_mutex_lock(&mutexP);
 
        // Critical Section
        item = i;
        printf("Producer에서 아이템 생산 :: %d\n",item);
 
        pthread_mutex_unlock(&mutexC);
    }
 
    return 0;
}
 
void *threadFuncC(void* arg)
{
    int i, get;
 
    for (i = 0; i < 100; i++)
    {
        pthread_mutex_lock(&mutexC);
 
        // Critical Section
        get = item;
        printf("Consumer에서 아이템 소비 :: %d\n",get);
 
        pthread_mutex_unlock(&mutexP);
    }
 
    return 0;
}
 
 
int main()
{
    // 프로듀서 컨슈머 스레드 선언
    pthread_t threadP, threadC;
 
    // 컨슈머는 아이템이 없을 때 행동하면 안되기에 초기에 lock으로 시작한다.
    pthread_mutex_lock(&mutexC);
 
    pthread_create(&threadP, NULL, threadFuncP, NULL);
    pthread_create(&threadC, NULL, threadFuncC, NULL);
 
    pthread_join(threadP, NULL);
    pthread_join(threadC, NULL);
 
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus







2. Mutex Condition


뮤텍스 컨디션은 다음 링크에서 자세히 설명되어있기에 설명은 생략한다.


http://www.crocus.co.kr/526


이를 이용한 프로듀서 컨슈머를 제작해보자.




3. 뮤텍스 컨디션(Mutex Condition)를 이용한 Producer and Consumer


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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <stdio.h>
#include <pthread.h>
 
// 뮤텍스 및 컨디션 선언
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
 
int item = -1;
 
void* threadFuncP(void* arg)
{
    int i;
 
    for (i = 0; i < 100; i++)
    {
        // mutex lock
        pthread_mutex_lock(&mutex);
 
        // critical section
        item = i;
        printf("Producer가 아이템을 생산 :: %d\n", item);
 
        // signal 을 통해 consumer를 깨울 준비를 한다.
        pthread_cond_signal(&cond);
 
        // producer은 아이템을 생산하였으니 다시 기다린다.
        pthread_cond_wait(&cond, &mutex);
 
        // wait가 끝이나면 unlock을 하고 for문을 준비한다.
        pthread_mutex_unlock(&mutex);
    }
 
    return 0;
}
 
void* threadFuncC(void* arg)
{
    int i, get;
 
    for (i = 0; i < 100; i++)
    {
        // mutex lock
        pthread_mutex_lock(&mutex);
 
        //critical section
        // item이 아직 도착하지 않았을 때(조건)
        // wait를 통해 기다린다.
        while (item == -1)
            pthread_cond_wait(&cond, &mutex);
 
        get = item;
        printf("Consumer이 아이템을 소비 :: %d\n", get);
        // 아이템을 소비하면 -1로 표현
        item = -1;
 
        // signal을 통해 producer를 깨울 준비를 한다.
        pthread_cond_signal(&cond);
 
        // 걸려있던 lock을 풀고 for문을 준비한다.
        pthread_mutex_unlock(&mutex);
    }
 
    return 0;
}
 
int main()
{
    pthread_t threadP, threadC;
 
    pthread_create(&threadP, NULL, threadFuncP, NULL);
    pthread_create(&threadC, NULL, threadFuncC, NULL);
 
    pthread_join(threadP, NULL);
    pthread_join(threadC, NULL);
 
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus







































반응형