I'm learning to use pthreads, mutexes and condition variables but things aren't going as expected.
MAIN THREAD: runs continuously, signals worker thread, reads from file_A.
WORKER THREAD: sleep until signal received, writes to file_A, back to sleep (should be repeatable)
So I understand a mutex is needed here to prevent both threads from reading/writing to and from the same file. I'm using a condition variable to signal the worker thread.
But for some reason, the worker thread only runs once. Do I need to reset the condition variable or do something else?
Worker thread function:
void* WriteTime(){
pthread_mutex_lock(&mutex);
pthread_cond_wait(&condition, &mutex);
/* Open File, Write to File, Close File */
pthread_mutex_unlock(&mutex);
}
Main Thread:
pthread_t timeThread;
pthread_create(&timeThread, NULL, &WriteTime, NULL);
while(gameConditionFulfilled == false){
/* Print status, gets user input into line */
/* If user enters "time", wake up WORKER_THREAD */
if(strcmp(line, "time")==0){
pthread_mutex_lock(&mutex);
pthread_cond_signal(&condition);
/* Read from file, print data, close file */
pthread_mutex_unlock(&mutex);
}
}
Also my understanding of the code above is like this:
The behavior is actually:
First off, you would want some sort of loop in WriteTime() -- returning causes pthread_exit() to be called. When pthread_create() starts a thread, it is started as if:
pthread_exit((*func)(arg));
Which raises the second point -- your compiler should have screamed at you about this, since your WriteTime() doesn’t return anything. Warnings are useful; they don’t need to be obeyed, but you should understand why they are presented.
To skip a couple of chapters, the idea of a condition variable is that it protects a “condition”; for example that there is data ready to read or write. You are using them like semaphores, but unlike semaphores, condition variables do not have any memory. Pthread_condition_wait() will only return if pthread_condition_(signal|broadcast)() is called WHILE the thread is waiting. If pthread_condition_signal() is called when nobody is waiting, nothing happens. So the idiomatic use of a condition variable is:
lock(mutex)
while (something_hasn’t_happened) {
wait(cond, mutex)
}
do something
unlock(mutex)