HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Simple mutex and conditional variable signal in C

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
simplemutexsignalconditionalandvariable

Problem

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
#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(&mutex);
if (status != 0) {
err_abort(status, "Lock mutex");
}
while (predicate_value == 0) {
printf("%s\n", "waiting");
status = pthread_cond_wait(&cond, &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(&mutex);
if (status != 0) {
err_abort(status, "Unlock mutex");
}
}
}

int main () {
int status = 0;
pthread_t work_thread_id;
status = pthread_create(&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(&mutex);
if (status != 0) {
err_abort(status, "Lock mutex main");
}
printf("%s\n", "changed value");
predicate_value = 1;
status = pthread_cond_signal(&cond);
if (status != 0) {
err_abort(status, "signal condition");
}
status = pthread_mutex_unlock(&mutex);
if (status != 0) {
err_abort(status, "Unlock mutex main");
}

Solution

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.

Context

StackExchange Code Review Q#149180, answer score: 2

Revisions (0)

No revisions yet.