Thread safety
- C course
- Advanced
- Lesson 23/83
- 5 min
Learn thread safety and data race concepts.
Thread safety
Thread safety means code works correctly when called by multiple threads at once. Unprotected access to shared data causes a data race.
A data race occurs when two threads access the same variable and at least one writes. The result is unpredictable: counter++ called 2000 times may not yield 2000. With a mutex you serialize access and prevent the race.
Data race
A data race is when concurrent access gives an ambiguous result. If two threads do counter++, some increments can be lost.
For example, two threads incrementing 1000 times each may give 1732 instead of 2000. With a mutex each increment becomes atomic and the result is always 2000. Compiler warnings and tools can detect races; but the safest way is to use a mutex.
Practice Race-free counter
Write void *worker(void *arg) with for (int i = 0; i < 100; i++) { pthread_mutex_lock(&lock); counter++; pthread_mutex_unlock(&lock); }. Create two threads, join them and print printf("counter=%d\n", counter);. With the mutex the result is 200.
Starter code
#include <stdio.h>
#include <pthread.h>
int counter = 0;
pthread_mutex_t lock;
// Add a for loop to worker (increment 100 times with mutex)
// Create two threads and join
// Print counter
int main(void) {
return 0;
}Sample solution
#include <stdio.h>
#include <pthread.h>
int counter = 0;
pthread_mutex_t lock;
void *worker(void *arg) {
for (int i = 0; i < 100; i++) {
pthread_mutex_lock(&lock);
counter++;
pthread_mutex_unlock(&lock);
}
return NULL;
}
int main(void) {
pthread_mutex_init(&lock, NULL);
pthread_t t1, t2;
pthread_create(&t1, NULL, worker, NULL);
pthread_create(&t2, NULL, worker, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("counter=%d\n", counter);
return 0;
}Expected output
counter=200
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Match safety concepts
| Term | Meaning |
|---|---|
mutex |
Prevents race |
data race |
Ambiguous access |
lock |
Acquires lock |
counter++ |
Increment operation |
2 How is a data race prevented?
- With fork
- With printf
- With a mutex Correct answer
- With exit
Explanation: A mutex serializes shared access.
3 Critical region
pthread_mutex_lock(&____);
counter++;
pthread_mutex_unlock(&lock);
pthread_mutex_lock(&lock);
counter++;
pthread_mutex_unlock(&lock);
Explanation: The critical region starts with lock.