`numThreads` is written before the child threads that read it are started, so there is an explicit happens-before relationship and no data race. Before `numThreads` is reset, the child thread are joined.
There is no bug in the program, it is legal to use non-atomic variables across threads as long as they're correctly sequenced.