Hello, I've noticed that the example in the current http://man7.org/linux/man-pages/man2/futex.2.html page has 2 issues: 1) The quoted output mismatches the actual output, i.e. the parent/child order is reversed. Man page output: $ ./futex_demo Parent (18534) 0 Child (18535) 0 Parent (18534) 1 Child (18535) 1 [..] Actual output: Child (21215) 0 Parent (21214) 0 Child (21215) 1 Parent (21214) 1 [..] Fix: --- futex_demo.c.orig 2019-10-14 19:36:23.292238650 +0200 +++ futex_demo.c 2019-10-14 19:36:58.599464636 +0200 @@ -108,8 +108,8 @@ futex1 = &iaddr[0]; futex2 = &iaddr[1]; - *futex1 = 0; /* State: unavailable */ - *futex2 = 1; /* State: available */ + *futex1 = 1; /* State: unavailable */ + *futex2 = 0; /* State: available */ /* Create a child process that inherits the shared anonymous mapping */ Note that this also fixes the comments. 2) As is, the fwait() either busy-waits or waits forever: static void fwait(int *futexp) { int s; while (1) { /* Is the futex available? */ const int zero = 0; if (atomic_compare_exchange_strong(futexp, &zero, 1)) break; /* Yes */ /* Futex is not available; wait */ s = futex(futexp, FUTEX_WAIT, 0, NULL, NULL, 0); // XXX => because 3rd arg (val) is 0 and not 1 this call // likely return s==-1 and sets errno==EAGAIN // (in our context) if (s == -1 && errno != EAGAIN) errExit("futex-FUTEX_WAIT"); } } See also: $ strace -o log -f ./futex_demo $ grep 'futex.*'EAGAIN log -c 17 The number varies, of course. Depending on the scheduling, this also may lead to a deadlock - most easily reproducible when running it multiple times under strace, e.g.: $ strace -o log -f ./futex_demo Parent (21488) 0 Child (21489) 0 ^C $ Reason: There is a race between atomic_compare_exchange_strong() and futex(.., FUTEX_WAIT, ..) where the first observes the futex value as 1 but the second as 0. Fix: set val argument of futex() to 1, i.e. the same value that failed to be set atomically: --- futex_demo.c.orig 2019-10-14 19:36:23.292238650 +0200 +++ futex_demo.c 2019-10-14 19:49:02.696404149 +0200 @@ -60,7 +60,7 @@ /* Futex is not available; wait */ - s = futex(futexp, FUTEX_WAIT, 0, NULL, NULL, 0); + s = futex(futexp, FUTEX_WAIT, 1, NULL, NULL, 0); if (s == -1 && errno != EAGAIN) errExit("futex-FUTEX_WAIT"); } With that: no deadlocks and: $strace -o log -f ./futex_demo $ grep 'futex.*'EAGAIN log -c 0 Best regards Georg -- Hofstadter's Law: "It always takes longer than you think it will take, even when you take into account Hofstadter's Law"