A new template for Lab 5 (Consumer Producer Assignment) based on the old one.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

98 lines
2.7 KiB

  1. /***** Global Includes *****/
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <time.h>
  5. /***** Local Includes *****/
  6. #include "queue.h"
  7. #include "thread.h"
  8. /***** Constants *****/
  9. #define TIME_TO_PRODUCE 1000 // milliseconds
  10. #define TIME_TO_CONSUME 1000 // milliseconds
  11. #define LOOP 10
  12. /***** Producer *****
  13. * The function called by the producer thread.
  14. *
  15. * TODO for students: This function does not lock the queue and will
  16. * ultimately race with the consumers. Experiment with locking and unlocking
  17. * the producer using the queueLock() and queueUnlock() functions.
  18. */
  19. void producer(queue *q)
  20. {
  21. for (int i = 0; i < LOOP; ++i)
  22. {
  23. // Pretend that expensive operations are occuring by sleeping.
  24. sleep_milliseconds(TIME_TO_PRODUCE);
  25. // Busy loop while the queue is full. (HINT THIS IS AN UNSYNCHRONIZED READ)
  26. while (queueIsFull(q));
  27. // Put the produced item onto the queue and print that the enqueue occured.
  28. enqueue(q, i+1);
  29. printf("producer: produced %d th.\n",i+1);
  30. }
  31. }
  32. /***** Consumer *****
  33. * The function called by the consumer threads.
  34. *
  35. * TODO for students: The consumers does not lock the queue when consuming
  36. * and ultimately race with the producer and other consumers. Experiment
  37. * with the queueLock() and queueUnlock() functions within this function.
  38. */
  39. void consumer(queue *q)
  40. {
  41. // Simulate the consumer's random quick arrival (Makes race conditions prominent)
  42. sleep_milliseconds((rand()%LOOP) * TIME_TO_CONSUME/LOOP);
  43. // Wait for an item to be in the queue. (HINT THIS IS AN UNSYNCHRONIZED READ)
  44. while (queueIsEmpty(q));
  45. // Pretend to consume
  46. sleep_milliseconds(TIME_TO_CONSUME);
  47. printf("------------------------------------>consumer: recieved %d.\n", dequeue(q));
  48. }
  49. int main()
  50. {
  51. // Initialize the queue. If the queue fails to initialize, kill the program.
  52. queue *q = queueInit();
  53. if (q == NULL)
  54. {
  55. fprintf(stderr, "main: Queue Init failed.\n");
  56. exit(1);
  57. }
  58. // Seed the random number generator using the system clock.
  59. unsigned int iseed = (unsigned int) time(NULL);
  60. srand(iseed);
  61. // Start one producer thread and as many consumer threads as specified above.
  62. thread_t pro, con[LOOP];
  63. create_thread(&pro, producer, q);
  64. for (int i = 0; i < LOOP; ++i)
  65. {
  66. sleep_milliseconds((rand() % 2) * 1000);
  67. create_thread(&con[i], consumer, q);
  68. }
  69. // Let the producers and consumers finish before cleaning up.
  70. wait_for_threads(&pro, 1);
  71. wait_for_threads(con, LOOP);
  72. // Clean up the queue.
  73. queueDestroy(q);
  74. #ifdef WINDOWS
  75. // If this is running in Windows, execute the "pause" shell command so that
  76. // the command prompt window doesn't close after this program finishes.
  77. system("pause");
  78. #endif
  79. return 0;
  80. }