Holy cow, I wrote a book!
Einstein discovered that simultaneity is relative.
This is also true of computing.
People will ask, "Is it okay to do X on one thread and Y on
another thread simultaneously?" Here are some examples:
You can answer this question knowing nothing about the internal
behavior of those operations. All you need to know are some physics
and the answers to much simpler questions about what is
valid sequential code.
Let's do a thought experiment with simultaneity.
Since simultaneity is relative, any code that does X and Y
simultaneously can be observed to have performed X before Y
or Y before X, depending on your frame of reference.
That's how the universe works.
So if it were okay to do them simultaneously, then it must
also be okay to do them one after the other, since they
do occur one after the other if you walk
past the computer in the correct direction.
Is it okay to use a handle after closing it?
Is it okay to unregister a wait event twice?
The answer to both questions is "No," and therefore
it isn't okay to do them simultaneously either.
If you don't like using physics to solve this problem, you can
also do it from a purely technical perspective.
Invoking a function is not an atomic operation. You prepare
the parameters, you call the entry point, the function does some
work, it returns. Even if you somehow manage to get both threads
to reach the function entry point simultaneously (even though as
we know from physics there is no such thing as true simultaneity),
there's always the possibility that one thread will get pre-empted
immediately after the "call" instruction has transferred control
to the first instruction of the target function,
while the other thread continues to completion.
After the second thread runs to completion, the pre-empted thread
gets scheduled and begins execution of the function body.
Under this situation, you effectively
called the two functions one after the
other, despite all your efforts to call them simultaneously.
Since you can't prevent this scenario from occurring,
you have to code with the possibility that it might actually happen.
Hopefully this second explanation will satisfy the people who don't believe
in the power of physics.
Personally, I prefer using physics.