2 * Procon1.Cpp - Producer/Consumer Demonstration Program 1 :Jss

Total Page:16

File Type:pdf, Size:1020Kb

2 * Procon1.Cpp - Producer/Consumer Demonstration Program 1 :Jss

Feb 20 09:29 procon1.cpp Page 1

1 /* 2 * "procon1.cpp" - producer/consumer demonstration program 1 :jss 3 * first attempt: UNsynchronized 4 * 5 * build with: c++ procon1.cpp -lpthread 6 */ 7 8 #include 9 #include 10 #include // for pthread functions 11 #include // for perror() 12 #include // for srand(), rand() 13 #include // for sleep() 14 using namespace std; 15 16 /***** B U F F E R C L A S S ***********************************/ 17 18 class Buffer { 19 public: 20 Buffer() { value = -1; } // ctor with initial default value 21 void set( string, int ); // a buffer object can assume a given value 22 int get( string ); // or return its current value 23 private: 24 int value; // value of the Buffer object 25 }; 26 27 void Buffer::set( string who, int val ) 28 { 29 cout << " > " << who << " writing " << val << endl; 30 value = val; 31 } 32 33 int Buffer::get( string who ) 34 { 35 cout << " < " << who << " reading " << value << endl; 36 return value; 37 } 38 39 /***** P R O D U C E R C L A S S *******************************/ 40 41 class Producer { 42 public: 43 Producer( Buffer &buf ): sharedLoc(buf) 44 { cout << "producer created" << endl; } 45 void run(); // method to simulate a producer 46 private: 47 Buffer &sharedLoc; // reference to global shared buffer 48 }; 49 50 // produce values 1-4 to shared buffer at random intervals 51 void Producer::run() 52 { 53 for (int count = 1; count <= 4; count++) 54 { 55 sleep( rand() % 3 + 1 ); // simulate some producer processing 56 sharedLoc.set( "producer", count); // send a new datum to buffer 57 } 58 cout << "producer finished." << endl; 59 } 60

Feb 20 09:29 procon1.cpp Page 2

61 /***** C O N S U M E R C L A S S *******************************/ 62 63 class Consumer { 64 public: 65 Consumer( Buffer &buf ): sharedLoc(buf) 66 { cout << "consumer created" << endl; } 67 void run(); // method to simulate a consumer 68 private: 69 Buffer &sharedLoc; // reference to global shared buffer 70 }; 71 72 // read & sum shared buffer 4 times at random times, report sum 73 void Consumer::run() 74 { 75 int sum = 0; // for running sum of buffer get values 76 for (int count = 1; count <= 4; count++) 77 { 78 sleep( rand() % 3 + 1 ); // simulate some consumer processing 79 sum += sharedLoc.get( "consumer" ); // retrieve a datum from buffer 80 } 81 cout << "consumer finished, sum = " << sum << endl; 82 } 83 84 /***** M A I N P R O G R A M C O D E *************************/ 85 86 Buffer buf; // this is the global shared buffer object 87 88 void *producer_thread(void *) 89 { 90 Producer p(buf); // instantiate one object of class Producer 91 p.run(); // be a producer 92 } 93 94 void *consumer_thread(void *) 95 { 96 Consumer c(buf); // instantiate one object of class Consumer 97 c.run(); // be a consumer 98 } 99 100 // main thread is the test-driver 101 int main() 102 { 103 pthread_t ptid, ctid; // producer, consumer thread IDs 104 105 srand(time(NULL)); // seed random number generator 106 cout << "\nThreaded Producer/Consumer Test, first attempt...\n\n"; 107 cout << "current buf value = " << buf.get("main") << endl; 108 // create & launch producer thread 109 if (pthread_create(&ptid, NULL, producer_thread, NULL) != 0) 110 perror("pthread_create() error, could not create producer thread"); 111 // create & launch consumer thread 112 if (pthread_create(&ctid, NULL, consumer_thread, NULL) != 0) 113 perror("pthread_create() error, could not create consumer thread"); 114 // wait for the 2 threads to finish 115 pthread_join(ptid, NULL); 116 pthread_join(ctid, NULL); 117 cout << "\nexiting program...\n"; 118 } Sample runs

~/400- c++ procon1.cpp -lpthread ~/400- a.out # RUN 1

Threaded Producer/Consumer Test, first attempt... < main reading -1 current buf value = -1 producer created consumer created > producer writing 1 < consumer reading 1 < consumer reading 1 > producer writing 2 > producer writing 3 < consumer reading 3 > producer writing 4 producer finished. < consumer reading 4 consumer finished, sum = 9

~/400- a.out # RUN 2

Threaded Producer/Consumer Test, first attempt... < main reading -1 current buf value = -1 producer created consumer created > producer writing 1 > producer writing 2 < consumer reading 2 > producer writing 3 < consumer reading 3 > producer writing 4 producer finished. < consumer reading 4 < consumer reading 4 consumer finished, sum = 13

~/400- a.out # RUN 3

Threaded Producer/Consumer Test, first attempt... < main reading -1 current buf value = -1 producer created consumer created < consumer reading -1 > producer writing 1 < consumer reading 1 > producer writing 2 < consumer reading 2 < consumer reading 2 consumer finished, sum = 4 > producer writing 3 > producer writing 4 producer finished. Feb 20 09:33 procon2.cpp Page 1

1 /* 2 * "procon2.cpp" - producer/consumer demonstration program 2 :jss 3 * second attempt: synchronized via busy-wait solution :-( 4 * 5 * build with: c++ procon2.cpp -lpthread 6 */ 7 8 #include 9 #include 10 #include 11 #include 12 #include // for pthread functions 13 #include // for sleep() 14 using namespace std; 15 16 /***** B U F F E R C L A S S ***********************************/ 17 18 class Buffer { 19 public: 20 Buffer() { value = -1; } // ctor with initial default value 21 void set( string, int ); // a buffer object can assume a given value 22 int get( string ); // or return its current value 23 private: 24 int value; // value of the Buffer object, -1 means "empty" 25 }; 26 27 void Buffer::set( string who, int val ) 28 { 29 cout << " > " << who << " writing " << val << endl; 30 while (value != -1) {} // wait to previous value to be consumed 31 value = val; // store new one 32 } 33 34 int Buffer::get( string who ) 35 { 36 int tmp; 37 while (value == -1) {} // wait for datum to be produced 38 cout << " < " << who << " reading " << value << endl; 39 tmp = value; value = -1; // consume it & "empty" buffer 40 return tmp; 41 } 42 43 /***** P R O D U C E R C L A S S *******************************/ 44 45 class Producer { 46 public: 47 Producer( Buffer &buf ): sharedLoc(buf) 48 { cout << "producer created\n"; } 49 void run(); // method to simulate a producer 50 private: 51 Buffer &sharedLoc; // reference to global shared buffer 52 }; 53 54 // produce values 1-4 to shared buffer at random intervals 55 void Producer::run() 56 { 57 for (int count = 1; count <= 4; count++) 58 { 59 sleep( rand() % 3 + 1 ); // simulate some producer processing 60 sharedLoc.set( "producer", count); // send a new datum to buffer 61 } 62 cout << "producer finished." << endl; 63 } 64

Feb 20 09:33 procon2.cpp Page 2

65 /***** C O N S U M E R C L A S S *******************************/ 66 67 class Consumer { 68 public: 69 Consumer( Buffer &buf ): sharedLoc(buf) 70 { cout << "consumer created\n"; } 71 void run(); // method to simulate a consumer 72 private: 73 Buffer &sharedLoc; // reference to global shared buffer 74 }; 75 76 // read & sum shared buffer 4 times at random times, report sum 77 void Consumer::run() 78 { 79 int sum = 0; // for running sum of buffer get values 80 for (int count = 1; count <= 4; count++) 81 { 82 sleep( rand() % 3 + 1 ); // simulate some consumer processing 83 sum += sharedLoc.get( "consumer" ); // retrieve a datum from buffer 84 } 85 cout << "consumer finished, sum = " << sum << endl; 86 } 87 88 /***** M A I N P R O G R A M C O D E *************************/ 89 90 Buffer buf; // this is the global shared buffer object 91 92 void *producer_thread(void *) 93 { 94 Producer p(buf); // instantiate one object of class Producer 95 p.run(); // be a producer 96 } 97 98 void *consumer_thread(void *) 99 { 100 Consumer c(buf); // instantiate one object of class Consumer 101 c.run(); // be a consumer 102 } 103 104 // main thread is the test-driver 105 int main() 106 { 107 pthread_t ptid, ctid; // producer, consumer thread IDs 108 109 srand(time(NULL)); // seed random number generator 110 cout << "\nThreaded Producer/Consumer Test w/ busy-wait...\n\n"; 111 // cout << "current buf value = " << buf.get("main") << endl; // can't do! 112 // create & launch producer thread 113 if (pthread_create(&ptid, NULL, producer_thread, NULL) != 0) 114 perror("pthread_create() error, could not create producer thread"); 115 // create & launch consumer thread 116 if (pthread_create(&ctid, NULL, consumer_thread, NULL) != 0) 117 perror("pthread_create() error, could not create consumer thread"); 118 // wait for the 2 threads to finish 119 pthread_join(ptid, NULL); 120 pthread_join(ctid, NULL); 121 cout << "\nexiting program...\n"; 122 }Feb 13 17:53 procon3.c Page 1

1/* 2 * "procon3.c" - producer/consumer demonstration program 3 :jss 3 * 3rd attempt: semaphore-controlled to guarantee correct results :-) 4 * 5 * build with: cc procon3.c -lpthread 7 */ 8 9#include 10 #include // for pthread functions 11 #include // for semaphores 12 13 /***** GLOBALS *****/ 14 int buf; // this is the global shared buffer object (uninitialized) 15 sem_t valueProduced; // semaphore from producer to consumer 16 sem_t valueConsumed; // semaphore from consumer to producer 17 18 void *producer_thread() 19 { 20 int count; 21 printf("producer created.\n"); 22 for (count = 1; count <= 4; count++) 23 { 24 sleep( rand() % 3 + 1 ); // simulate some producer processing 25 printf(" > producer writing %d\n", count); 26 sem_wait(&valueConsumed); // 'P' (wait) consumer 27 /*** critical region ***/ 28 buf = count; // send a new datum to buffer 29 sem_post(&valueProduced); // 'V' (signal) consumer 30 } 31 printf("producer finished.\n"); 32 } 33 34 void *consumer_thread() 35 { 36 int count, bufcopy; 37 int sum = 0; // for running sum of buffer get values 38 printf("consumer created.\n"); 39 for (count = 1; count <= 4; count++) 40 { 41 sleep( rand() % 3 + 1 ); // simulate some consumer processing 42 sem_wait(&valueProduced); // 'P' (wait) producer 43 /*** critical region ***/ 44 bufcopy = buf; // grab local copy of shared buffer 45 sem_post(&valueConsumed); // 'V' (signal) producer 46 printf(" < consumer reading %d\n", bufcopy); 47 sum += bufcopy; // running total 48 } 49 printf("consumer finished, sum = %d\n", sum); // will always be 1+2+3+4 50 } 51 52 // main thread is the test-driver 53 int main() 54 { 55 pthread_t ptid, ctid; // producer, consumer thread IDs 56 57 puts("\nSemaphore-controlled Threaded Producer/Consumer Test...\n"); 58 srand(time(NULL)); // seed random number generator 59 // initialize semaphores appropriately 60 if (sem_init(&valueProduced, 0, 0) == -1) // value=0 61 perror("sem_init(): could not init valueProduced semaphore"); 62 if (sem_init(&valueConsumed, 0, 1) == -1) // value=1 63 perror("sem_init(): could not init valueConsumed semaphore"); 64 // create & launch producer thread 65 if (pthread_create(&ptid, NULL, producer_thread, NULL) != 0) 66 perror("pthread_create() error, could not create producer thread"); 67 // create & launch consumer thread 68 if (pthread_create(&ctid, NULL, consumer_thread, NULL) != 0) 69 perror("pthread_create() error, could not create consumer thread"); 70 // wait for the 2 threads to finish 71 pthread_join(ptid, NULL); 72 pthread_join(ctid, NULL); 73 puts("\nexiting program...\n"); 74 }

Recommended publications