a context switch
When more threads want to run than there are CPU cores, the operating system shares each core by time, letting one thread run for a slice, then pausing it and letting another run, over and over - fast enough that they all seem to advance together. The act of pausing one thread and resuming another on a core is a context switch. Picture a single chess master playing several boards at once: she steps to one board, makes her move, walks to the next, and so on - each board's position is left exactly as it was, ready for her to pick up later.
The 'context' is everything the paused thread needs in order to resume later exactly where it left off: the contents of the CPU registers (including the program counter, which marks the next instruction, and the stack pointer), and related bookkeeping. To switch, the OS saves the running thread's context (copies those registers out to memory), then loads the next thread's previously-saved context back into the registers, so the CPU picks up that thread mid-stride as if it had never stopped. A scheduler in the kernel decides who runs next and for how long. Switching between two threads in the same process is relatively cheap because they share an address space; switching between threads in different processes also involves changing the memory mappings, which costs more.
Why context switches matter for our hazards: a context switch can land at almost any instruction boundary, including in the middle of a read-modify-write or any critical section. That is precisely the mechanism by which two threads' operations get interleaved - the OS pauses thread A halfway through count++ and runs thread B, producing the lost-update bug. Context switches also have a cost: they take time, and they can evict useful data from the CPU's cache, so a program that switches too frantically spends effort shuffling threads instead of doing work. This is part of why threads are not free and why more threads is not always faster.
On a single core running three threads, the OS might run thread 1 for 10 milliseconds, save its registers, restore thread 2's, run it for 10 ms, and so on - cycling so fast that to a human all three appear to run simultaneously, even though only one is ever on the core at a time.
Save one thread's registers, load another's - the core is time-shared, one thread at a time.
Because a switch can occur between any two machine instructions, you cannot assume even a single line of C runs without interruption - that assumption is the source of the read-modify-write bug. Context switches also cost real time, so they are not free.