Processes vs Threads
source: https://w3.cs.jmu.edu/kirkpams/OpenCSF/Books/csf/html/ProcVThreads.html
Each process has it own unique virtual memory space, this includes code segment, heap, stack, …
Every process begins by executing the instructions contained usually define in main() , the %pc register contains a pointer to the next instruction to be executed. This single, logical sequence of executing instructions within a process is known as a thread of execution, which we typically just call a thread.
💡 A thread: A coherent and independent execution sequence of software instructions.
Multithreading**
just like the thread that start executing main() , a process cloud have multiple threads each one has it entry point. To maintain the logical flow of these additional threads, each thread is assigned a separate stack. However, all of the other segments of memory, including the code, global data, heap, and kernel, are shared.
💡 rocesses act as containers for resource ownership. As the process runs, it may request access to files stored on the disk, open network connections, or request the creation of a new window on the desktop. All of these resources are allocated to the process, not individual threads.
Thread context switch Vs. process context switch
The main distinction between a thread switch and a process switch is
that during a thread switch, the virtual memory space remains the same,
while it does not during a process switch.
Both types involve handing control over to the operating system kernel
to perform the context switch. The process of switching in and out of
the OS kernel along with the cost of switching out the registers is the
largest fixed cost of performing a context switch.
A more fuzzy cost is that a context switch messes with the processors
cacheing mechanisms. Basically, when you context switch, all of the
memory addresses that the processor "remembers" in its cache effectively
become useless. The one big distinction here is that when you change
virtual memory spaces, the processor's Translation Lookaside Buffer
(TLB) or equivalent gets flushed making memory accesses much more
expensive for a while. This does not happen during a thread switch.
💡 At the same time, the lack of isolation between threads in a single process can also lead to some disadvantages. If one thread crashes due to a segmentation fault or other error, all other threads and the entire process are killed. This situation can lead to data and system corruption if the other threads were in the middle of some important task.
- As an example, assume that the application is a server program with one thread responsible for logging all requests and a separate thread for handling the requests. If the request handler thread crashes before the logging thread has a chance to write the request to its log file, there would be no record of the request. The system administrators left to determine what went wrong would have no information about the request, so they may waste a lot of time validating other requests that were all good.


Thread Models
Thread per connection model
- Each unit of work (request, connection, etc) gets a thread.
- Thread performs blocking I/O
- May need more threads than CPU processors for maximum parallelism.
- Breaks down as number of requests becomes very large.
- Apache web server is an example of this mod

Event-driven threading model
- Uses asynchronous I/O and callbacks
- Uses an event loop
- NGINX, Node.js are examples of this model
- No reason to have more threads than CPU processors
- No waiting in threads
- Author's suggestion: try this pattern first for your application.

💡 you should always try the
Event-driven threading modelfirst, if that does not work well then try the older model theThread per connection

