A software thread is the “Smallest sequence of programmed instructions that can be managed independently by a scheduler” [Wikipedia]
A thread has its own:
- Program counter
- Registers
- Stack
- Thread-local memory (better to avoid in general)
- Threads of a process share everything else, e.g. Program code, constants, Network connections
To make code thread-safe, it is important to know what objects are shared and know when they are shared. The difficulty depends on the context.
For more information, please see: Making Code Thread-Safe by Kyle Knoepfel and Introduction to multi-threading and vectorization by Matti Kortelainen.