Why It Gets Worse: Shared Data
Understand why threads accessing shared data without proper synchronization lead to inconsistent and unpredictable results. Explore a practical example of threads incrementing a shared variable and learn how thread scheduling impacts data accuracy in concurrent programs.
We'll cover the following...
We'll cover the following...
The simple thread example you saw in the last lesson was useful in showing how threads are created and how they can run in different orders depending on how the scheduler decides to run them. What it doesn’t show you, though, is how threads interact when they access shared data.
Interaction of threads
Let’s imagine a simple example where two threads wish to update a global shared variable. The code you’ll study is in the coding widget below.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "common.h"
#include "common_threads.h"
int max;
volatile int counter = 0; // shared global variable
void *mythread(void *arg) {
char *letter = arg;
int i; // stack (private per thread)
printf("%s: begin [addr of i: %p]\n", letter, &i);
for (i = 0; i < max; i++) {
counter = counter + 1; // shared: only one
}
printf("%s: done\n", letter);
return NULL;
}
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "usage: main-first <loopcount>\n");
exit(1);
}
max = atoi(argv[1]);
pthread_t p1, p2;
printf("main: begin [counter = %d] [%x]\n", counter,
(unsigned int) &counter);
Pthread_create(&p1, NULL, mythread, "A");
Pthread_create(&p2, NULL, mythread, "B");
// join waits for the threads to finish
Pthread_join(p1, NULL);
Pthread_join(p2, NULL);
printf("main: done\n [counter: %d]\n [should: %d]\n",
counter, max*2);
return 0;
}
Here are a few notes ...