#include #include #include #include #include #define NUM_T1 2 #define NUM_T2 4 #define MAX_COUNT 10 bool done = false; // Flag to indicate completion int count = 0; // Count simulating buffer pthread_mutex_t count_mutex; // Mutex variable pthread_cond_t count_cond; // Conditional variable void * T1 (void *t) { int tid = * (int *)t; printf ("T1[%d] started\n", tid); while (!done) { pthread_mutex_lock (&count_mutex); if (count == MAX_COUNT) { printf ("T1[%d] Count already at max\n", tid); } else { count++; pthread_cond_signal (&count_cond); printf ("T1[%d] count = %d\n", tid, count); } pthread_mutex_unlock (&count_mutex); sleep (1); } printf ("T1[%d] thread done.\n", tid); pthread_exit (NULL); } void * T2 (void *t) { int tid = * (int *)t; printf ("T2 [%d] started\n", tid); while (!done) { pthread_mutex_lock (&count_mutex); if (count <= 0) { printf ("T2[%d] waiting for buffer\n", tid); pthread_cond_wait (&count_cond, &count_mutex); printf ("T2[%d] released from wait\n", tid); } if (!done) { count--; printf ("T2[%d] count = %d\n", tid, count); } else { printf ("T2[%d] Broadcast received with done flag set\n", tid); } pthread_mutex_unlock (&count_mutex); sleep (2); } printf ("T2[%d] thread done.\n", tid); pthread_exit (NULL); } int main (int argc, char *argv[]) { int thread_id [NUM_T1 + NUM_T2]; pthread_t thread[NUM_T1 + NUM_T2]; pthread_attr_t attr; int t; void *status; /* Initialize mutex and condition variable objects */ pthread_mutex_init (&count_mutex, NULL); pthread_cond_init (&count_cond, NULL); /* Initialize and set thread detached attribute */ pthread_attr_init (&attr); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_JOINABLE); /* Spawn the threads */ for (t = 0; t < NUM_T1; t++) { thread_id[t] = t; pthread_create (&thread[t], &attr, T1, &thread_id[t]); } for (t = 0; t < NUM_T2; t++) { thread_id[NUM_T1+t] = NUM_T1 + t; pthread_create (&thread[t + NUM_T1], &attr, T2, &thread_id[NUM_T1+t]); } sleep (5); done = true; /* Free attribute and wait for the other threads */ pthread_cond_broadcast (&count_cond); for (t = 0; t < NUM_T1 + NUM_T2; t++) pthread_join (thread[t], &status); printf ("Main: program completed. Exiting. Count = %d\n", count); /* Clean up and exit */ pthread_attr_destroy (&attr); pthread_mutex_destroy (&count_mutex); pthread_cond_destroy (&count_cond); pthread_exit (NULL); } T1[0] started T1[1] started T1[0] count = 1 T2 [2] started T2[2] count = 0 T1[1] count = 1 T2 [3] started T2[3] count = 0 T2 [4] started T2[4] waiting for buffer T2 [5] started T2[5] waiting for buffer T1[1] count = 1 T2[4] released from wait T2[4] count = 0 T1[0] count = 1 T2[5] released from wait T2[5] count = 0 T2[2] waiting for buffer T2[3] waiting for buffer T1[1] count = 1 T2[2] released from wait T2[2] count = 0 T1[0] count = 1 T2[3] released from wait T2[3] count = 0 T2[4] waiting for buffer T2[5] waiting for buffer T1[1] count = 1 T2[4] released from wait T2[4] count = 0 T1[0] count = 1 T2[5] released from wait T2[5] count = 0 T2[2] waiting for buffer T1[1] count = 1 T2[2] released from wait T2[2] count = 0 T2[3] waiting for buffer T1[0] count = 1 T2[3] released from wait T2[3] count = 0 T2[4] thread done. T1[1] thread done. T1[0] thread done. T2[5] thread done. T2[2] thread done. T2[3] thread done. Main: program completed. Exiting. Count = 0