思路相同
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#define CAPACITY 4
int buffer1[CAPACITY];
int buffer2[CAPACITY];
int in1;
int out1;
int in2;
int out2;
int buffer_is_empty1()
{
return in1 == out1;
}
int buffer_is_full1()
{
return (in1 + 1) % CAPACITY == out1;
}
int buffer_is_empty2()
{
return in2 == out2;
}
int buffer_is_full2()
{
return (in2 + 1) % CAPACITY == out2;
}
int get_item1()
{
int item;
item = buffer1[out1];
out1 = (out1 + 1) % CAPACITY;
return item;
}
void put_item1(int item)
{
buffer1[in1] = item;
in1 = (in1 + 1) % CAPACITY;
}
int get_item2()
{
int item;
item = buffer2[out2];
out2 = (out2 + 1) % CAPACITY;
return item;
}
void put_item2(int item)
{
buffer2[in2] = item;
in2 = (in2 + 1) % CAPACITY;
}
typedef struct {
int value;
pthread_mutex_t mutex;
pthread_cond_t cond;
} sema_t;
void sema_init(sema_t *sema, int value)
{
sema->value = value;
pthread_mutex_init(&sema->mutex, NULL);
pthread_cond_init(&sema->cond, NULL);
}
void sema_wait(sema_t *sema)
{
pthread_mutex_lock(&sema->mutex);
while (sema->value <= 0)
pthread_cond_wait(&sema->cond, &sema->mutex);
sema->value--;
pthread_mutex_unlock(&sema->mutex);
}
void sema_signal(sema_t *sema)
{
pthread_mutex_lock(&sema->mutex);
++sema->value;
pthread_cond_signal(&sema->cond);
pthread_mutex_unlock(&sema->mutex);
}
sema_t mutex;
sema_t wait_empty_buffer1;
sema_t wait_full_buffer1;
sema_t wait_empty_buffer2;
sema_t wait_full_buffer2;
#define ITEM_COUNT (CAPACITY * 2)
void *consume(void *arg)
{
int i;
int item;
for (i = 0; i < ITEM_COUNT; i++) {
sema_wait(&wait_full_buffer2);
sema_wait(&mutex);
item = get_item2();
printf("%c ",item);
sema_signal(&mutex);
sema_signal(&wait_empty_buffer2);
}
return NULL;
}
void *counter(void *arg)
{
int i;
int item;
for (i = 0; i < ITEM_COUNT; i++) {
sema_wait(&wait_full_buffer1);
sema_wait(&mutex);
item = get_item1();
// printf("counter1:%c ",item);
sema_wait(&wait_empty_buffer2);
item = item - 32;
// printf("counter2:%c ",item);
put_item2(item);
sema_signal(&mutex);
sema_signal(&wait_full_buffer2);
sema_signal(&wait_empty_buffer1);
}
return NULL;
}
void *produce(void *arg)
{
int i;
int item;
for (i = 0; i < ITEM_COUNT; i++) {
sema_wait(&wait_empty_buffer1);
sema_wait(&mutex);
item = 'a' + i;
// printf("produce:%c \n",item);
put_item1(item);
sema_signal(&wait_full_buffer1);
sema_signal(&mutex);
}
return NULL;
}
int main()
{
pthread_t consumer_tid;
pthread_t counter_tid;
sema_init(&mutex, 1);
sema_init(&wait_empty_buffer1, CAPACITY - 1);
sema_init(&wait_full_buffer1, 0);
sema_init(&wait_empty_buffer2, CAPACITY - 1);
sema_init(&wait_full_buffer2, 0);
pthread_create(&counter_tid, NULL, counter, NULL);
pthread_create(&consumer_tid, NULL, consume, NULL);
produce(NULL);
pthread_join(counter_tid, NULL);
pthread_join(consumer_tid, NULL);
return 0;
}