/* * Copyright ©2026 Justin Hsia and Amber Hu. All rights reserved. * Permission is hereby granted to students registered for University of * Washington CSE 333 for use solely during Winter Quarter 2026 for * purposes of the course. No other use, copying, distribution, or * modification is permitted without prior written consent. Copyrights * for third-party components of this work must be honored. Instructors * interested in reusing these course materials should contact the * authors. */ #include #include #include #include #include #include #include "SimpleQueue.h" using std::cout; using std::endl; using std::string; using std::thread; // Thread safe print that prints the given str on a line void thread_safe_print(string str); // Produces NUM_DISHES dishes of the given type void producer(string dish_type); // Eats 2 * NUM_DISHES dishs void consumer(); const int NUM_DISHES = 6; // # dishes created by each producer static SimpleQueue queue; // queue of dishes static unsigned int seed = time(NULL); // initialize random sleep time static pthread_mutex_t write_lock; // mutex for cout int main(int argc, char** argv) { pthread_mutex_init(&write_lock, NULL); // Your task: Make the two producers and the single consumer // all run concurrently (hint: use pthreads) producer("Mulgikapsad"); producer("kama"); consumer(); pthread_mutex_destroy(&write_lock); return EXIT_SUCCESS; } void thread_safe_print(string str) { pthread_mutex_lock(&write_lock); // Only one thread can hold the lock at a time, making it safe to // use cout. If we didn't lock before using cout, the order of things // put into the stream could be mixed up. cout << str << endl; pthread_mutex_unlock(&write_lock); } // You should NOT modify this method at all void producer(string dish_type) { for (int i = 0; i < NUM_DISHES; i++) { queue.Enqueue(dish_type); thread_safe_print(dish_type + " ready!"); int sleep_time = rand_r(&seed) % 500 + 1; std::this_thread::sleep_for(std::chrono::milliseconds(sleep_time)); } } // You should NOT modify this method at all void consumer() { for (int i = 0; i < NUM_DISHES * 2; i++) { bool successful = false; string dish_type; while (!successful) { while (queue.IsEmpty()) { // Sleep for a bit and then check again int sleep_time = rand_r(&seed) % 800 + 1; std::this_thread::sleep_for(std::chrono::milliseconds(sleep_time)); } successful = queue.Dequeue(&dish_type); } thread_safe_print(dish_type + " eaten!"); } }