Definition Threads in a process are like processes with shared memory. They have their own registers, program counter, and stack. explicit statements should be made if any memory is specific to a thread.
Unlike processes, who execute in their own memory space by default, threads allow multiple execution in the same memory space. This means they share code, data, file descriptors e.t.c. They are also relatively light-weight and cheap because of memory sharing.
Threads are used for concurrent programming such as network requests handling.
Functions In this article, Unix threads will be used for examples.
pthread_create returns 0 on success, other code on error. An example would be
To make sure a thread waits until another thread finishes their execution, we would use pthread_join
pthread_join returns 0 on success, other code on error. Please note: only call this once on a thread per thread. Multiple calls on the same thread lead to undefined behaviour.
pthread_exit is a great tool if we would like to exit early in a thread.
Another use case of pthread_join is to clean up resources of a thread on exit. It is also possible to let a thread clean up its resources automatically on exit by making it detachable.
pthread_detach returns 0 on success, error number otherwise. Please note that calling pthread_detach on a detached thread leads to undefined behaviour.
Also, detached threads are not joinable which means the main thread are not going to wait on them before returning.
To wait on all sub-threads when exiting, a main thread would have to call pthread_exit in the end to wait on all threads (whether joinable or detached).
You may also set attributes for a thread. An example is:
set a thread as joinable
We prefer threads over processes for following reasons:
- Threads are light-weight
- Threads have lower overheads for creation and context switching
- Threads share memory by default