Created
May 22, 2016 12:41
-
-
Save anonymous/9b7349423c46b89c7d8e65ace38827b2 to your computer and use it in GitHub Desktop.
Operating System Concepts course Lab 4 Task 1 source
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <pthread.h> | |
#include <iostream> | |
#include <unistd.h> | |
#include <semaphore.h> | |
#include <stdlib.h> | |
#define BUFFER_SIZE 5 | |
#define MAX_SLEEP_TIME 15 | |
typedef int buffer_item; | |
buffer_item buffer[BUFFER_SIZE]; | |
int count, in, out; | |
pthread_mutex_t mutex; | |
sem_t empty, full; | |
int insert_item(buffer_item item) { | |
if (count == BUFFER_SIZE) return -1; | |
buffer[in] = item; | |
in = (in + 1) % BUFFER_SIZE; | |
++count; | |
return 0; | |
} | |
int remove_item(buffer_item * item) { | |
if (count == 0) return -1; | |
*item = buffer[out]; | |
out = (out + 1) % BUFFER_SIZE; | |
--count; | |
return 0; | |
} | |
int parse_int(const char * str) { | |
int result = 0; | |
if (str == NULL || str[0] == '\0') return -1; | |
for (int i = 0; str[i] != '\0'; ++i) { | |
if (str[i] >= '0' && str[i] <= '9') | |
result = result * 10 + str[i] - '0'; | |
else | |
return -1; | |
} | |
return result; | |
} | |
void * producer(void * arg) { | |
buffer_item r; | |
while (true) { | |
// sleep for a random period of time | |
sleep(rand() % MAX_SLEEP_TIME); | |
// generate a random number | |
r = rand(); | |
std::cout << "producer produced " << r << std::endl; | |
sem_wait(&empty); | |
pthread_mutex_lock(&mutex); | |
if (insert_item(r)) { | |
std::cout << "report error condition on insert_item" << std::endl; | |
} | |
pthread_mutex_unlock(&mutex); | |
sem_post(&full); | |
} | |
pthread_exit(0); | |
} | |
void * consumer(void * arg) { | |
buffer_item r; | |
while (true) { | |
// sleep for a random period of time | |
sleep(rand() % MAX_SLEEP_TIME); | |
sem_wait(&full); | |
pthread_mutex_lock(&mutex); | |
if (remove_item(&r)) { | |
std::cout << "report error condition on remove_item" << std::endl; | |
} else { | |
std::cout << "consumer consumed " << r << std::endl; | |
} | |
pthread_mutex_unlock(&mutex); | |
sem_post(&empty); | |
} | |
pthread_exit(0); | |
} | |
int main(int argc, char * argv[]) { | |
// Get command line arguments argv[1], argv[2], argv[3] | |
if (argc < 4) { | |
std::cout << "Argument Error" << std::endl; | |
return -1; | |
} | |
int sleep_time = parse_int(argv[1]); | |
int producer_count = parse_int(argv[2]); | |
int consumer_count = parse_int(argv[3]); | |
if (sleep_time < 0 || producer_count < 0 || consumer_count < 0) { | |
std::cout << "Argument Error" << std::endl; | |
return -1; | |
} | |
// Initialize buffer | |
in = 0; | |
out = 0; | |
count = 0; | |
// Initialize sem and lock | |
pthread_mutex_init(&mutex, NULL); | |
sem_init(&empty, 0, 5); | |
sem_init(&full, 0, 0); | |
// Create producer thread(s) | |
pthread_t producers[100]; | |
pthread_t consumers[100]; | |
for (int i = 0; i < producer_count; ++i) { | |
pthread_create(&producers[i], NULL, producer, (void *)NULL); | |
} | |
// Create consumer thread(s) | |
for (int i = 0; i < consumer_count; ++i) { | |
pthread_create(&consumers[i], NULL, consumer, (void *)NULL); | |
} | |
// Sleep | |
sleep(sleep_time); | |
// Exit | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment