Challenge 1: A Race Condition, Observed Across Multiple Runs — Possible Solution ==================================================================== #include #include int counter = 0; void *increment(void *arg) { for (int i = 0; i < 100000; i++) { counter++; } return NULL; } int main() { pthread_t t1, t2; pthread_create(&t1, NULL, increment, NULL); pthread_create(&t2, NULL, increment, NULL); pthread_join(t1, NULL); pthread_join(t2, NULL); printf("counter = %d\n", counter); return 0; } Compile with -pthread and run several times: $ gcc -pthread race.c -o race $ ./race counter = 187342 $ ./race counter = 193021 $ ./race counter = 200000 $ ./race counter = 179884 No -- the final value is NOT consistently 200,000. It varies from run to run, and is usually LESS than 200,000 (occasionally it might even land on exactly 200,000 by chance, but that's not reliable). This matches the chapter's own explanation precisely: counter++ is a read-modify-write sequence, not a single atomic operation, so when both threads' operations interleave at the machine-instruction level, one thread's increment can be silently overwritten/lost by the other's concurrent read-modify-write sequence -- exactly the non-deterministic behavior the chapter predicts. WHY THIS WORKS AS AN ANSWER ------------------------------ This runs the program multiple times and reports genuinely varying results (not a single fixed wrong number), correctly identifies the final value as usually less than 200,000 rather than claiming it's always wrong by the same amount, and ties the observed non-determinism back to the read-modify-write mechanism the chapter names as the root cause.