|
Notifying Threads of State Changes
in Pthreads |
|
Prof. David Bernstein |
| Computer Science Department |
| bernstdh@jmu.edu |
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "tax_lib.h"
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static int should = -1; // Shared variable
static void
*thread_entry(void *arg)
{
pthread_mutex_lock(&mutex);
// Start of critical section
if (should_tax()) should = 1;
else should = 0;
// End of critical section
pthread_mutex_unlock(&mutex);
record_status(); // This takes a long time
return NULL;
}
int
main(void)
{
float rate, sales, tax;
int waiting;
pthread_t helper;
void *result;
pthread_create(&helper, NULL, thread_entry, NULL);
rate = 0.05;
sales = total_sales();
waiting = 1;
while (waiting) // Poll until the helper thread is done
{
pthread_mutex_lock(&mutex);
// Start of critical section
if (should != -1) waiting = 0;
// End of critical section
pthread_mutex_unlock(&mutex);
}
// Start of critical section
if (should) tax = sales * rate;
else tax = 0.0;
// End of critical section
printf("Tax: %5.2f\n", tax);
pthread_join(helper, &result);
exit(0);
}
pthread_cond_t variablesstatic pthread_cond_t example = PTHREAD_COND_INITIALIZER
acquire the mutex
while (predicate) block on the condition variable
when notified use the shared variable
relinquish the mutex
acquire the mutex
use the shared variable
relinquish the mutex
notify
int pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex)
cv
|
The condition variable to wait for |
mutex
|
The mutex associated with the condition variable |
| Return | 0 on success; a positive error number on error |
When Called: mutex is relinquished and the calling thread
is blocked.
When Unblocked: mutex is obtained (so that the shared variable
can be used).
pthread_cond_wait() returns when notified
but there is no guarantee that the predicate is satisfied
so it must be re-checked
int pthread_cond_broadcast(pthread_cond_t *cv)
cv
|
The condition variable the threads are/may be blocking on |
| Return | 0 on success; a positive error number on error |
Note: All blocking threads will be notified but which one(s) are scheduled is arbitrary.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "tax_lib.h"
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
static int should = -1; // Shared variable
static void
*thread_entry(void *arg)
{
pthread_mutex_lock(&mutex);
// Start of critical section
if (should_tax()) should = 1;
else should = 0;
// End of critical section
pthread_mutex_unlock(&mutex);
pthread_cond_broadcast(&cv);
record_status(); // This takes a long time
return NULL;
}
int
main(void)
{
float rate, sales, tax;
pthread_t helper;
void *result;
pthread_create(&helper, NULL, thread_entry, NULL);
rate = 0.05;
sales = total_sales();
pthread_mutex_lock(&mutex);
while (should == -1)
{
pthread_cond_wait(&cv, &mutex);
}
if (should) tax = sales * rate;
else tax = 0.0;
pthread_mutex_unlock(&mutex); // Not necessary for this example
printf("Tax: %5.2f\n", tax);
pthread_join(helper, &result);
exit(0);
}
int pthread_cond_init(pthread_cond_t *cv, const pthread_condattr_t *attr)
cv
|
The condition variable to be initialized |
attr
|
The attributes to use (of NULL for the default attributes) |
| Return | 0 on success; a positive error number on error |