Merge a5fe16d5aaddda10fcdb9bf16f482e02bb0025b6 into b70121d377cb6005eb65f12b098cd5decd905669

This commit is contained in:
Justin McLain 2023-07-20 02:07:08 -07:00 committed by GitHub
commit 76a6d916ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 222 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,31 @@
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0; t<NUM_THREADS; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
}

View File

@ -0,0 +1,191 @@
#include<iostream>
#include<semaphore.h>
#include<stdio.h>
#include<iomanip>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#define Producer_Steps 5//producer thread iterations
#define Consumer_Steps 5 //consumer thread iterations
#define NUM_THREADS 4 //count of threads
#define BUFFER_SIZE 10 //max capacity of buffer
void * Produce(void *threadIn);
void * Consume(void *ThreadIn);
void Insert(int threadIn);
void Remove(int threadIn);
sem_t full;
sem_t empty;
int cookieCount;
pthread_mutex_t mutex;
// Main
// executes thread code from codeIn
//error checks for proper input
int main(int argc, char *argv[]){
int ret_creats;
//check semaphore containments for max and empty
sem_init(&full, 0, BUFFER_SIZE);
sem_init(&empty, 0, 0);
//make the consumer and produce array for threads
pthread_t Consumer[NUM_THREADS];
pthread_t Producer[NUM_THREADS];
//define the mutex
pthread_mutex_init(&mutex,NULL);
long c = 0;
while (c < NUM_THREADS){
ret_creats = pthread_create(&Consumer[c], NULL, Consume, (void *) c);
if(ret_creats){
//error check for test case
std::cerr << "Error in Consumer create" << std::endl;
exit(-1);
}
c++;
}
long p = 0;
while (p < NUM_THREADS){
ret_creats = pthread_create(&Producer[p], NULL, Produce, (void *) p);
if(ret_creats){
//error check for test case
std::cerr << "Error in producer create" << std::endl;
exit(-1);
}
p++;
}
//this deletes the total number of threads
//once the endpoint of Consumer is reached
int k = 0;
while (k < NUM_THREADS){
pthread_join(Consumer[k], NULL);
k++;
}
//this deletes the total number of threads
//one the endpoint of Producer is reaches
int l = 0;
while(l < NUM_THREADS){
pthread_join(Producer[l], NULL);
l++;
}
//end print statement
std::cout << "All threads are done." << std::endl;
std::cout << "Resources cleaned up." << std::endl;
pthread_mutex_destroy(&mutex);
pthread_exit(NULL);
// delete the semaphores.
sem_destroy(&full);
sem_destroy(&empty);
return 0;
}
//this function inserts, adds, and configures
// threads to add one
void Insert(int threadIn){
int codeIn;
//attempt mutex lock
codeIn = pthread_mutex_lock(&mutex);
//error check #1
if(codeIn !=0){
std::cerr << "producer #" << threadIn << "Error in the lock" << std::endl;
exit(-1);
}
else{
cookieCount++;
std::cerr <<"producer #" << threadIn << " inserted a cookie." << " Total: " << cookieCount << std::endl;
}
//this step unlocks the mutex
codeIn = pthread_mutex_unlock(&mutex);
//if error then halt the program and quit
//otherwise just disregard
if(codeIn != 0){
std::cerr << "producer #" << threadIn << " Error in the Unlock" << std::endl;
}
}
//this function will take the cookieCount out
// of the counter and lock and relock & repeat
void Remove(int threadIn) {
//placeholder for the pthread_mutex
//and lock
int codeIn = pthread_mutex_lock(&mutex);
//error check for lock
if (codeIn != 0) {
std::cerr <<"consumer #" << threadIn << ": Failed in Remove: lock" << std::endl;
exit(-1);
}
else {
//decrement the counter
cookieCount--;
std::cerr << "consumer #" << threadIn << " removed a cookie. " << "Total: " << cookieCount << std::endl;
}
//this unlocks the mutex when the function is being called
codeIn = pthread_mutex_unlock(&mutex);
//error check for unlock
if (codeIn != 0) {
std::cerr << "consumer: #" << threadIn << ": Failed in Remove Unlock" << std::endl;
exit(-1);
}
}
//producer thread will alternate between inserting
//an item and sleeping for 1 second. It will do so for 5
//times. Call sleep(1) to sleep for 1 second between iterations.
void * Produce(void *threadIn) {
long temp = (long)threadIn;
int i = 0;
while (i < Producer_Steps) {
sem_wait(&full);
Insert(temp);
sem_post(&empty);
//sleep and increment
sleep(1);
i++;
}
//finish
pthread_exit(NULL);
}
//cosumer thread runs eacdh thread to delete int
//countwidbuffer
void * Consume(void * threadIn){
//convert value to int
long temp = (long)threadIn;
int i = 0;
while (i < Consumer_Steps) {
sem_wait(&empty);
Remove(temp);
sem_post(&full);
//sleep and increment
sleep(1);
i++;
}
//finish
pthread_exit(NULL);
}