Simple mutex and conditional variable signal in C I'm new to multithreading in C so I made a toy program that uses a mutex and a conditional variable to communicate between two threads. do_work performs a task every 1 second (task could take longer than 1 second). Is this implementation free from deadlocks and race conditions? Anything else I might be missing? 

#include &lt;pthread.h&gt;
#include "errors.h"

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int predicate_value = 0;

void *do_work(void *work) {
    int status = 0;
    int i = 0;
    while (1) {
        status = pthread_mutex_lock(&amp;mutex);
        if (status != 0) {
            err_abort(status, "Lock mutex");
        }
        while (predicate_value == 0) {
            printf("%s\n", "waiting");
            status = pthread_cond_wait(&amp;cond, &amp;mutex);
            if (status != 0) {
                err_abort(status, "Wait on condition");
            }
        }
        if (predicate_value != 0) {
            printf("doing some work: %d\n", i);
            ++i;
            predicate_value = 0;
        }
        status = pthread_mutex_unlock(&amp;mutex);
        if (status != 0) {
            err_abort(status, "Unlock mutex");
        }
    }
}

int main () {
    int status = 0;
    pthread_t work_thread_id;
    status = pthread_create(&amp;work_thread_id, NULL, do_work, NULL);
    if (status != 0) {
        err_abort(status, "Create work thread");
    }
    while (1) {
        if (predicate_value == 0) {
            status = pthread_mutex_lock(&amp;mutex);
            if (status != 0) {
                err_abort(status, "Lock mutex main");
            }
            printf("%s\n", "changed value");
            predicate_value = 1;
            status = pthread_cond_signal(&amp;cond);
            if (status != 0) {
                err_abort(status, "signal condition");
            }
            status = pthread_mutex_unlock(&amp;mutex);
            if (status != 0) {
                err_abort(status, "Unlock mutex main");
            }
            printf("%s\n", "time to sleep");            
        }
        sleep(1);
    }
}
Needs volatile keyword
The way your program is written, predicate_value needs to be a volatile int instead of a normal int.  This is because you are reading it without locking the mutex in main(), and writing to it in do_work() from another thread.
Another way to avoid the problem is to ensure that you only ever read the variable with the mutex locked.