producer_consumer.c

Download
c 161 lines 3.9 KB
  1// producer_consumer.c
  2// μƒμ‚°μž-μ†ŒλΉ„μž νŒ¨ν„΄ (경계 버퍼)
  3#include <stdio.h>
  4#include <stdlib.h>
  5#include <pthread.h>
  6#include <unistd.h>
  7#include <stdbool.h>
  8#include <time.h>
  9
 10#define BUFFER_SIZE 5
 11#define NUM_ITEMS 20
 12
 13// 경계 버퍼
 14typedef struct {
 15    int buffer[BUFFER_SIZE];
 16    int count;      // ν˜„μž¬ μ•„μ΄ν…œ 수
 17    int in;         // λ‹€μŒ μ‚½μž… μœ„μΉ˜
 18    int out;        // λ‹€μŒ μΆ”μΆœ μœ„μΉ˜
 19
 20    pthread_mutex_t mutex;
 21    pthread_cond_t not_full;   // 버퍼가 가득 μ°¨μ§€ μ•ŠμŒ
 22    pthread_cond_t not_empty;  // 버퍼가 λΉ„μ–΄μžˆμ§€ μ•ŠμŒ
 23
 24    bool done;      // 생산 μ™„λ£Œ ν”Œλž˜κ·Έ
 25} BoundedBuffer;
 26
 27BoundedBuffer* buffer_create(void) {
 28    BoundedBuffer* bb = malloc(sizeof(BoundedBuffer));
 29    bb->count = 0;
 30    bb->in = 0;
 31    bb->out = 0;
 32    bb->done = false;
 33
 34    pthread_mutex_init(&bb->mutex, NULL);
 35    pthread_cond_init(&bb->not_full, NULL);
 36    pthread_cond_init(&bb->not_empty, NULL);
 37
 38    return bb;
 39}
 40
 41void buffer_destroy(BoundedBuffer* bb) {
 42    pthread_mutex_destroy(&bb->mutex);
 43    pthread_cond_destroy(&bb->not_full);
 44    pthread_cond_destroy(&bb->not_empty);
 45    free(bb);
 46}
 47
 48void buffer_put(BoundedBuffer* bb, int item) {
 49    pthread_mutex_lock(&bb->mutex);
 50
 51    // 버퍼가 가득 찼으면 λŒ€κΈ°
 52    while (bb->count == BUFFER_SIZE) {
 53        printf("[μƒμ‚°μž] 버퍼 가득 μ°Έ. λŒ€κΈ°...\n");
 54        pthread_cond_wait(&bb->not_full, &bb->mutex);
 55    }
 56
 57    // μ•„μ΄ν…œ μ‚½μž…
 58    bb->buffer[bb->in] = item;
 59    bb->in = (bb->in + 1) % BUFFER_SIZE;
 60    bb->count++;
 61
 62    printf("[μƒμ‚°μž] μ•„μ΄ν…œ %d 생산 (버퍼: %d/%d)\n",
 63           item, bb->count, BUFFER_SIZE);
 64
 65    // μ†ŒλΉ„μžμ—κ²Œ μ•Œλ¦Ό
 66    pthread_cond_signal(&bb->not_empty);
 67
 68    pthread_mutex_unlock(&bb->mutex);
 69}
 70
 71int buffer_get(BoundedBuffer* bb, int* item) {
 72    pthread_mutex_lock(&bb->mutex);
 73
 74    // 버퍼가 λΉ„μ–΄μžˆκ³  생산 μ™„λ£Œ μ•„λ‹ˆλ©΄ λŒ€κΈ°
 75    while (bb->count == 0 && !bb->done) {
 76        printf("[μ†ŒλΉ„μž] 버퍼 λΉ„μ–΄μžˆμŒ. λŒ€κΈ°...\n");
 77        pthread_cond_wait(&bb->not_empty, &bb->mutex);
 78    }
 79
 80    // 버퍼가 λΉ„μ–΄μžˆκ³  생산 μ™„λ£Œλ©΄ μ’…λ£Œ
 81    if (bb->count == 0 && bb->done) {
 82        pthread_mutex_unlock(&bb->mutex);
 83        return 0;  // 더 이상 μ•„μ΄ν…œ μ—†μŒ
 84    }
 85
 86    // μ•„μ΄ν…œ μΆ”μΆœ
 87    *item = bb->buffer[bb->out];
 88    bb->out = (bb->out + 1) % BUFFER_SIZE;
 89    bb->count--;
 90
 91    printf("[μ†ŒλΉ„μž] μ•„μ΄ν…œ %d μ†ŒλΉ„ (버퍼: %d/%d)\n",
 92           *item, bb->count, BUFFER_SIZE);
 93
 94    // μƒμ‚°μžμ—κ²Œ μ•Œλ¦Ό
 95    pthread_cond_signal(&bb->not_full);
 96
 97    pthread_mutex_unlock(&bb->mutex);
 98    return 1;  // 성곡
 99}
100
101void buffer_set_done(BoundedBuffer* bb) {
102    pthread_mutex_lock(&bb->mutex);
103    bb->done = true;
104    pthread_cond_broadcast(&bb->not_empty);  // λͺ¨λ“  μ†ŒλΉ„μž 깨움
105    pthread_mutex_unlock(&bb->mutex);
106}
107
108// μƒμ‚°μž μŠ€λ ˆλ“œ
109void* producer(void* arg) {
110    BoundedBuffer* bb = (BoundedBuffer*)arg;
111
112    for (int i = 1; i <= NUM_ITEMS; i++) {
113        usleep((rand() % 500) * 1000);  // 0~500ms λŒ€κΈ°
114        buffer_put(bb, i);
115    }
116
117    printf("[μƒμ‚°μž] 생산 μ™„λ£Œ\n");
118    buffer_set_done(bb);
119
120    return NULL;
121}
122
123// μ†ŒλΉ„μž μŠ€λ ˆλ“œ
124void* consumer(void* arg) {
125    BoundedBuffer* bb = (BoundedBuffer*)arg;
126    int item;
127
128    while (buffer_get(bb, &item)) {
129        usleep((rand() % 800) * 1000);  // 0~800ms 처리 μ‹œκ°„
130    }
131
132    printf("[μ†ŒλΉ„μž] μ†ŒλΉ„ μ™„λ£Œ\n");
133    return NULL;
134}
135
136int main(void) {
137    srand(time(NULL));
138
139    BoundedBuffer* bb = buffer_create();
140
141    pthread_t prod;
142    pthread_t cons[2];
143
144    // μƒμ‚°μž 1λͺ…
145    pthread_create(&prod, NULL, producer, bb);
146
147    // μ†ŒλΉ„μž 2λͺ…
148    pthread_create(&cons[0], NULL, consumer, bb);
149    pthread_create(&cons[1], NULL, consumer, bb);
150
151    // λŒ€κΈ°
152    pthread_join(prod, NULL);
153    pthread_join(cons[0], NULL);
154    pthread_join(cons[1], NULL);
155
156    buffer_destroy(bb);
157    printf("\nν”„λ‘œκ·Έλž¨ μ’…λ£Œ\n");
158
159    return 0;
160}