Example Code -
Using Condition
Variables
Αυτό το παράδειγμα παρουσιάζει την χρήση πολλών ρουτινών για μεταβλητές
συνθηκών σε Pthread. Η κύρια ρουτίνα δημιουργεί 3 νήματα. Τα 2 κάνουν
κάποια δουλειά και ενημερώνουν μια μεταβλητή "count". Η τρίτη περιμένει
μέχρι η μεταβλητή να πάρει μία ορισμένη τιμή.
#include <pthread.h> #include <stdio.h> #include <stdlib.h>
#define NUM_THREADS 3 #define TCOUNT 10 #define COUNT_LIMIT 12
int count = 0; int thread_ids[3] = {0,1,2}; pthread_mutex_t count_mutex; pthread_cond_t count_threshold_cv;
void *inc_count(void *t) { int i; long my_id = (long)t;
for (i=0; i<TCOUNT; i++) { pthread_mutex_lock(&count_mutex); count++;
/* Check the value of count and signal waiting thread when condition is reached. Note that this occurs while mutex is locked. */ if (count == COUNT_LIMIT) { pthread_cond_signal(&count_threshold_cv); printf("inc_count(): thread %ld, count = %d Threshold reached.\n", my_id, count); } printf("inc_count(): thread %ld, count = %d, unlocking mutex\n", my_id, count); pthread_mutex_unlock(&count_mutex);
/* Do some "work" so threads can alternate on mutex lock */ sleep(1); } pthread_exit(NULL); }
void *watch_count(void *t) { long my_id = (long)t;
printf("Starting watch_count(): thread %ld\n", my_id);
/* Lock mutex and wait for signal. Note that the pthread_cond_wait routine will automatically and atomically unlock mutex while it waits. Also, note that if COUNT_LIMIT is reached before this routine is run by the waiting thread, the loop will be skipped to prevent pthread_cond_wait from never returning. */ pthread_mutex_lock(&count_mutex); if (count<COUNT_LIMIT) { pthread_cond_wait(&count_threshold_cv, &count_mutex); printf("watch_count(): thread %ld Condition signal received.\n", my_id); count += 125; printf("watch_count(): thread %ld count now = %d.\n", my_id, count); } pthread_mutex_unlock(&count_mutex); pthread_exit(NULL); }
int main (int argc, char *argv[]) { int i, rc; long t1=1, t2=2, t3=3; pthread_t threads[3]; pthread_attr_t attr;
/* Initialize mutex and condition variable objects */ pthread_mutex_init(&count_mutex, NULL); pthread_cond_init (&count_threshold_cv, NULL);
/* For portability, explicitly create threads in a joinable state */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); pthread_create(&threads[0], &attr, watch_count, (void *)t1); pthread_create(&threads[1], &attr, inc_count, (void *)t2); pthread_create(&threads[2], &attr, inc_count, (void *)t3);
/* Wait for all threads to complete */ for (i=0; i<NUM_THREADS; i++) { pthread_join(threads[i], NULL); } printf ("Main(): Waited on %d threads. Done.\n", NUM_THREADS);
/* Clean up and exit */ pthread_attr_destroy(&attr); pthread_mutex_destroy(&count_mutex); pthread_cond_destroy(&count_threshold_cv); pthread_exit(NULL);
}
|