- 본 내용은 Linux (Ubuntu 14.04 lts)를 기반으로 제작되었습니다. -
세마포어를 이용하여, 프로듀서와 컨슈머를 제작해 본다.
실생활의 예로는, 동영상을 볼 때, 버퍼링을 통해 일정 범위를 받아두고 시청자가 시청할 수 있게되고,
네이버, 다음, 구글 지도처럼 버퍼링을 통해 일정 부분을 계속 볼 수 있게 하는 방식들이 있다.
( 세마포어를 이용하지 않고, 스레드 및 공유변수를 이용하여 만든 코드는 아래 주소에 있다.
알고리즘은 다음과 같다.
Producer Algorithm
- produce 세마포어는 처음 생산해야 하니 1로 초기화,
1. producer 스레드는 produce 세마포어를 wait (P) 한다.
- consumer 스레드에서 produce 세마포어를 post (V) 해주기 전 까지는
- producer 스레드에서 for문을 돌다가 sem_wait(&produce);에서 sleep하게 된다.
2. 아이템 하나를 공유변수 storagebox에 넣어준다.
3. producer 스레드는 컨슘 세마포어를 post (V) 한다.
Consumer Algorithm
- consume 세마포어는 처음에 가져갈 것이 없으니 0으로 초기화 한다.
1. consumer 스레드는 consume 세마포어를 wait (P) 한다.
- producer 스레드에서 consume 세마포어를 post (V) 해주기 전 까지는
- consumer 스레드에서 for문을 돌다가 sem_wait(&consume);에서 sleep하게 된다.
2. 공유변수 storagebox에서 아이템 변수로 받아낸다.
3. consumer 스레드는 produce 세마포어를 post (V) 해준다.
소스 코드
주석에서는 공장, 마트를 통해 비유를 해 두었다.
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 | #include <stdio.h> #include <pthread.h> #include <semaphore.h> sem_t produce, consume; int storagebox; // 아이템 보관함(1개만 저장 가능) void *producerRoutine(void *argumentPointer) { int i, item; for(i = 0; i < 10000; i ++) { item = i; // 하나 생산했으니 다른 곳에서 // storagebox를 접근하지 못하도록 한다. (생산 공장 문을 닫는다.) sem_wait(&produce); // storagebox에 아이템(i)를 넣어준다. // 단 하나의 제품만 슈퍼마켓에 넣어준다. printf("Producer message :: Give item to storagebox :: %d\n",item); storagebox = i; // 그 후 소비하는 곳에서 // 아이템을 가져갈 수 있도록 V를 해준다.(슈퍼마켓 문을 연다.) sem_post(&consume); } return NULL; } void *consumerRoutine(void *argumentPointer) { int i, item; for(i = 0; i < 10000; i ++) { // 아이템 하나를 받아오기 위해 // 다른 곳에서 storagebox를 접근하지 못하도록 한다.(슈퍼마켓 문을 닫는다.) sem_wait(&consume); // consumer item변수에 storagebox에 있던 // 아이템을 넣어준다. (한명만 물건을 사도록 한다.) item = storagebox; printf("Consumer message :: Take item from storagebox :: %d\n",item); // 다시 생산 할 수 있도록 V를 해준다. (생산 공장 문을 연다.) sem_post(&produce); } return NULL; } int main() { pthread_t producerID, consumerID; // 처음에는 생산을 해야되고 소비할 것이 없으니 각각 1,0으로 초기화한다. sem_init(&produce, 0, 1); sem_init(&consume, 0, 0); pthread_create(&producerID, NULL, producerRoutine, NULL); pthread_create(&consumerID, NULL, consumerRoutine, NULL); // 스레드 조인 pthread_join(producerID, NULL); pthread_join(consumerID, NULL); printf("Finish Producer and Consumer !! \n"); return 0; } // This source code Copyright belongs to Crocus // If you want to see more? click here >> | Crocus |
데드락이 일어나는지 다음 동영상을 통해 확인해 보고,
프로듀서 컨슈머가 어떻게 작동하는지 이해해 보자.
'Applied > Network' 카테고리의 다른 글
소켓 프로그래밍 - (24) 뮤텍스(Mutex)를 이용한 멀티 스레드 통신 (0) | 2016.11.17 |
---|---|
소켓 프로그래밍 - (23) Mutex Condition 개념 및 소스 코드 (6) | 2016.11.11 |
소켓 프로그래밍 - (21) 데드락(Deadlock) 개념 및 소스 코드 (0) | 2016.11.10 |
소켓 프로그래밍 - (20) Semaphore 개념 및 소스 코드 (9) | 2016.10.31 |
소켓 프로그래밍 - (19) Mutex 개념 및 소스 코드 (0) | 2016.10.31 |