diff --git "a/notes/\347\224\237\347\224\243\350\200\205\346\266\210\350\262\273\350\200\205/Producer-consumer-problem.png" "b/notes/\347\224\237\347\224\243\350\200\205\346\266\210\350\262\273\350\200\205/Producer-consumer-problem.png" new file mode 100644 index 0000000000..0f91534a99 Binary files /dev/null and "b/notes/\347\224\237\347\224\243\350\200\205\346\266\210\350\262\273\350\200\205/Producer-consumer-problem.png" differ diff --git "a/notes/\347\224\237\347\224\243\350\200\205\346\266\210\350\262\273\350\200\205/pthread_cc" "b/notes/\347\224\237\347\224\243\350\200\205\346\266\210\350\262\273\350\200\205/pthread_cc" new file mode 100644 index 0000000000..2a7a889284 --- /dev/null +++ "b/notes/\347\224\237\347\224\243\350\200\205\346\266\210\350\262\273\350\200\205/pthread_cc" @@ -0,0 +1,31 @@ +#include +#include +#include + +#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 +#include +#include +#include +#include +#include +#include + + + +#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); +}