Home | Projects | Notes > Multi-Threading (POSIX Threads) > Introduction to Threads

Introduction to Threads

 

What are Threads?

 

process-and-threads

 

 

Argument Passing

Make sure that you always pass the persistent memory as an argument to the thread (e.g., static variable or dynamically allocated variables on the heap). Do not pass the caller's local variables or stack memory whose lifetime is bound to the caller's lifetime because they will go away when the caller terminates.

 

Race Condition on Thread Creation

Race condition on thread creation refers to an indeterministic situation where which thread's instruction is going to be executed first immediately after the fork point.

 

race-condition-on-thread-creation

 

99.9% of the time time 'Instruction 1' will be executed first due to the scheduling overhead, but it is a good practice as a programmer not to assume which instruction is going to be executed first when writing a multi-threaded program.

 

Thread Termination

Three ways in which threads can be terminated:

If main thread terminates its threads will be automatically terminated by default, but not vice-versa. To prevent this from happening, use pthread_exit(); API in the main thread. This is mostly used in cases where the main thread is only required to spawn threads and leave the threads to do their job.

Termination of the spawned threads will not affect any other threads including the main thread.

 

Example - Hello World

Following program will create one thread, which is called the main thread, and that main thread will execute the function main.

 

Resource Sharing Among Threads

 

resource-sharing-among-threads

 

Operating system allocates resources to threads - Memory, CPU, access to hardware, etc.

All threads are siblings. There is no parent-child (having extra privileges) relationship between threads of the same process; no hierarchy.

Every thread has its own life-cycle (birth, life and death) independent from other threads in the system. (Exception: If main thread terminates its threads will be automatically terminated by default, but not vice-versa.)

Multiple threads of the same process share the same virtual address space of that process except that they have their own stack memory. Resources (that does not use the stack memory) allocated by one thread is visible to the rest of the threads. (e.g., Heap memory, sockets, file descriptors, global variables, etc.)

Stack memory is private to each thread.

 

Thread Stack Memory Management

 

thread-stack-memory-management

 

All spawned threads share the process' virtual memory space. (No separate virtual memory space for spawned threads.) But, each stack memory segment is private to the corresponding thread.

 

Thread Scheduling

Kernel (OS) does not schedule processes, but it schedules threads. Thread is a schedulable entity, not a process. Thread, a basic unit of execution flow, is to be allocated (by the OS) to the CPU for execution.

However, this rule is violated in certain error conditions:

The race condition on thread creation is due to the fact that which thread the kernel chooses to allocate CPU; the parent thread or the spawned child thread.

Kernel schedules threads on multiple CPUs as per the scheduling policy (e.g., FCFS, SJF).

 

 

References

Sagar, A. (2022). Part A - Multithreading & Thread Synchronization - Pthreads [Video file]. Retrieved from https://www.udemy.com/course/multithreading_parta/