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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define BUFFER_SIZE 10
typedef struct {
int buffer[BUFFER_SIZE];
int count;
int in;
int out;
pthread_mutex_t mutex;
pthread_cond_t not_full;
pthread_cond_t not_empty;
} CircularBuffer;
void buffer_init(CircularBuffer* cb) {
cb->count = 0;
cb->in = 0;
cb->out = 0;
pthread_mutex_init(&cb->mutex, NULL);
pthread_cond_init(&cb->not_full, NULL);
pthread_cond_init(&cb->not_empty, NULL);
}
void buffer_put(CircularBuffer* cb, int item) {
pthread_mutex_lock(&cb->mutex);
// 等待缓冲区不满
while (cb->count == BUFFER_SIZE) {
pthread_cond_wait(&cb->not_full, &cb->mutex);
}
cb->buffer[cb->in] = item;
cb->in = (cb->in + 1) % BUFFER_SIZE;
cb->count++;
// 通知消费者
pthread_cond_signal(&cb->not_empty);
pthread_mutex_unlock(&cb->mutex);
}
int buffer_get(CircularBuffer* cb) {
pthread_mutex_lock(&cb->mutex);
// 等待缓冲区不空
while (cb->count == 0) {
pthread_cond_wait(&cb->not_empty, &cb->mutex);
}
int item = cb->buffer[cb->out];
cb->out = (cb->out + 1) % BUFFER_SIZE;
cb->count--;
// 通知生产者
pthread_cond_signal(&cb->not_full);
pthread_mutex_unlock(&cb->mutex);
return item;
}
// 生产者线程
void* producer(void* arg) {
CircularBuffer* cb = (CircularBuffer*)arg;
for (int i = 0; i < 100; i++) {
buffer_put(cb, i);
printf("Produced: %d\n", i);
}
return NULL;
}
// 消费者线程
void* consumer(void* arg) {
CircularBuffer* cb = (CircularBuffer*)arg;
for (int i = 0; i < 100; i++) {
int item = buffer_get(cb);
printf("Consumed: %d\n", item);
}
return NULL;
}
int main() {
CircularBuffer cb;
buffer_init(&cb);
pthread_t prod, cons;
pthread_create(&prod, NULL, producer, &cb);
pthread_create(&cons, NULL, consumer, &cb);
pthread_join(prod, NULL);
pthread_join(cons, NULL);
pthread_mutex_destroy(&cb.mutex);
pthread_cond_destroy(&cb.not_full);
pthread_cond_destroy(&cb.not_empty);
return 0;
}
|