Skip to content

Instantly share code, notes, and snippets.

Created May 22, 2016 12:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save anonymous/9b7349423c46b89c7d8e65ace38827b2 to your computer and use it in GitHub Desktop.
Save anonymous/9b7349423c46b89c7d8e65ace38827b2 to your computer and use it in GitHub Desktop.
Operating System Concepts course Lab 4 Task 1 source
#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