{
Threads are the primary mechanism that operating systems provide for enabling concurrent execution. Modern operating systems ensure that each thread has fair access to the CPU. Understanding how to create threads (often referred to as spawning treads) and understanding their impact are fundamental skills for programmers wanting to make use of multi-core CPUs.
}
{
threads “don’t scale.” What does that mean?
Every thread requires its own memory, and by implication, we’ll eventually exhaust our system’s memory. Before that terminal point, though, thread creation begins to trigger slowdowns in other areas. As the number of threads to schedule increases, the OS scheduler’s work increases. When there are many threads to schedule, deciding which thread to schedule next takes more time.
Spawning threads is not free. It demands memory and CPU time. Switching between threads also invalidates caches.
}
{
if you’re thinking that sleeping is not a representative workload, It asks each thread to enter a spin loop. spin loop sterategy is better(performance) than sleep strategy.
}
{
It’s also possible to use both: sleep for the bulk of the time and a spin loop towards the end.
Second, CPU-intensive multithreading doesn’t scale well past the number of physical cores.
}
join is an extension of the thread metaphor. When threads are spawned, these are said to have forked from their parent thread. To join threads means to weave these back together again.
In practice, join means wait for the other thread to finish. The join() function instructs the OS to defer scheduling the calling thread until the other thread finishes.
{
.join()//means guarantee - waiting for All Threads to Finish Using join Handles
. A JoinHandle is an owned value that, when we call the join method on it, will wait for its thread to finish
}