Lab6: add monitor code
This commit is contained in:
parent
24d42d2c05
commit
338988bbc1
1 changed files with 95 additions and 0 deletions
95
lab6/demos/monitor.c
Normal file
95
lab6/demos/monitor.c
Normal file
|
@ -0,0 +1,95 @@
|
|||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct {
|
||||
int* buffer;
|
||||
int buffer_len;
|
||||
int buffer_cap;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t not_full;
|
||||
pthread_cond_t not_empty;
|
||||
} monitor_t;
|
||||
|
||||
volatile monitor_t monitor;
|
||||
|
||||
monitor_t* init_monitor(int buffer_cap) {
|
||||
monitor_t* monitor = malloc(sizeof(monitor_t));
|
||||
|
||||
monitor->buffer = calloc(buffer_cap, sizeof(int));
|
||||
monitor->buffer_len = 0;
|
||||
monitor->buffer_cap = buffer_cap;
|
||||
pthread_mutex_init(&monitor->mutex, NULL);
|
||||
pthread_cond_init(&monitor->not_full, NULL);
|
||||
pthread_cond_init(&monitor->not_empty, NULL);
|
||||
|
||||
return monitor;
|
||||
}
|
||||
|
||||
void destroy_monitor(monitor_t* monitor) {
|
||||
pthread_mutex_destroy(&monitor->mutex);
|
||||
pthread_cond_destroy(&monitor->not_full);
|
||||
pthread_cond_destroy(&monitor->not_empty);
|
||||
|
||||
free(monitor->buffer);
|
||||
free(monitor);
|
||||
}
|
||||
|
||||
void produce(monitor_t* monitor, int item) {
|
||||
pthread_mutex_lock(&monitor->mutex);
|
||||
while (monitor->buffer_len == monitor->buffer_cap) {
|
||||
pthread_cond_wait(&monitor->not_full, &monitor->mutex);
|
||||
}
|
||||
monitor->buffer[monitor->buffer_len] = item;
|
||||
monitor->buffer_len += 1;
|
||||
pthread_cond_signal(&monitor->not_empty);
|
||||
pthread_mutex_unlock(&monitor->mutex);
|
||||
}
|
||||
|
||||
int consume(monitor_t* monitor) {
|
||||
pthread_mutex_lock(&monitor->mutex);
|
||||
while (monitor->buffer_len == 0) {
|
||||
pthread_cond_wait(&monitor->not_empty, &monitor->mutex);
|
||||
}
|
||||
|
||||
monitor->buffer_len -= 1;
|
||||
int item = monitor->buffer[monitor->buffer_len];
|
||||
pthread_cond_signal(&monitor->not_full);
|
||||
pthread_mutex_unlock(&monitor->mutex);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void* producer_func(void* arg) {
|
||||
monitor_t* monitor = arg;
|
||||
|
||||
for (int i = 0; i < 20; i++) {
|
||||
produce(monitor, i);
|
||||
printf("Produced item %d\n", i);
|
||||
}
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
void* consumer_func(void* arg) {
|
||||
monitor_t* monitor = arg;
|
||||
for (int i = 0; i < 20; i++) {
|
||||
int item = consume(monitor);
|
||||
printf("Consumed item %d\n", item);
|
||||
}
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
pthread_t thread_producer, thread_consumer;
|
||||
|
||||
fprintf(stderr, "Line: %d\n", __LINE__);
|
||||
monitor_t* monitor = init_monitor(3);
|
||||
|
||||
pthread_create(&thread_producer, NULL, producer_func, (void*) monitor);
|
||||
pthread_create(&thread_consumer, NULL, consumer_func, (void*) monitor);
|
||||
|
||||
pthread_join(thread_producer, NULL);
|
||||
pthread_join(thread_consumer, NULL);
|
||||
|
||||
destroy_monitor(monitor);
|
||||
}
|
Loading…
Reference in a new issue