<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Anish Roy</title>
    <description>The latest articles on DEV Community by Anish Roy (@pshycodr).</description>
    <link>https://dev.to/pshycodr</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2204485%2F1b03a3ff-48f7-41b9-86c3-e61e07a607f4.png</url>
      <title>DEV Community: Anish Roy</title>
      <link>https://dev.to/pshycodr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pshycodr"/>
    <language>en</language>
    <item>
      <title>Process, Threads and Goroutines</title>
      <dc:creator>Anish Roy</dc:creator>
      <pubDate>Thu, 19 Feb 2026 06:21:51 +0000</pubDate>
      <link>https://dev.to/pshycodr/process-threads-and-goroutines-95l</link>
      <guid>https://dev.to/pshycodr/process-threads-and-goroutines-95l</guid>
      <description>&lt;h2&gt;
  
  
  What Is a Process?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgf2sismmye75zf2ivur9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgf2sismmye75zf2ivur9.png" alt="Chrome tabs process" width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A program is an executable file on disk.&lt;/p&gt;

&lt;p&gt;When the operating system loads that file into memory and starts execution, it becomes a process.&lt;/p&gt;

&lt;p&gt;A process has its own:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Memory Address&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Registers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Program Counter&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stack and Heap memory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I/O and system resources&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key property is isolation.&lt;/p&gt;

&lt;p&gt;Each process has its own resources, and one process cannot access or interact with another process directly.&lt;br&gt;&lt;br&gt;
Although it is possible to communicate with another process via IPC (Inter-Process Communication) and pipes, they need to be intentionally set up.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;Google Chrome runs each tab in a separate process. If one tab crashes or malfunctions, other tabs keep running. That isolation comes from process boundaries.&lt;/p&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Heavyweight&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expensive context switching&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Higher memory usage&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The operating systems must save registers, memory mappings, and kernel data structures also know as PCB(Process Control Blocks) on every context switch between process executions.&lt;/p&gt;


&lt;h2&gt;
  
  
  What Is a Thread?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmkh8xeli2z3kddxj0qki.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmkh8xeli2z3kddxj0qki.png" alt="Threads Diagram" width="400" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A thread is the unit of execution inside a process. Its like a subset of the process that runs inside the process boundaries.&lt;/p&gt;

&lt;p&gt;Every process has at least one thread, called the main thread. Many processes run multiple threads.&lt;/p&gt;

&lt;p&gt;Threads within the same process has same:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;memory address&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;heap and global variables&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, each thread have their own stack and registers Because threads share memory, communication is fast. No need for inter process communication.&lt;/p&gt;

&lt;p&gt;But this introduces risk.&lt;/p&gt;

&lt;p&gt;any faulty thread can crash the entire process.&lt;/p&gt;

&lt;p&gt;Context switching between threads is faster than between processes because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;No memory context switch&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Less kernel level operations&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Still, thread switching requires kernel involvement. That overhead adds up in highly concurrent systems.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Problem With Heavy Threads
&lt;/h2&gt;

&lt;p&gt;OS threads are expensive:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Large stack memory, mostly around 1 MB&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Kernel managed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expensive to create and destroy&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A blocking system call will block the entire thread&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you spawn thousands of threads, memory usage explodes.&lt;/p&gt;

&lt;p&gt;This is where Go changes the model.&lt;/p&gt;


&lt;h2&gt;
  
  
  What Is a Goroutine?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbi9iah64c0trhfgaiyav.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbi9iah64c0trhfgaiyav.png" alt="Goroutines example" width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A goroutine is a lightweight unit of execution managed by the Go runtime, not the operating system.&lt;/p&gt;

&lt;p&gt;You start one by prefixing a function call with the &lt;code&gt;go&lt;/code&gt; keyword:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;speak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thats it.&lt;/p&gt;

&lt;p&gt;The main function itself runs as a goroutine.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Goroutines Work
&lt;/h3&gt;

&lt;p&gt;Go uses an &lt;strong&gt;M:N&lt;/strong&gt; scheduling model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;M goroutines&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;N OS threads&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;M is usually much larger than N. Which means the Go runtime scheduler multiplexes many goroutines onto fewer OS threads.&lt;/p&gt;

&lt;p&gt;On a logical CPU:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;One OS thread runs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One goroutine executes at a time&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Many runnable goroutines wait in a local queue&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When a goroutine blocks on I/O, the runtime:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Parks the thread&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Moves other runnable goroutines from that thread to another thread&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and Keeps CPU cores busy. This avoids wasting resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Goroutines Are Lightweight
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Initial stack around 2 KB&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stack grows dynamically&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Context switching happens in user space&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No full kernel switches for goroutine scheduling&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can run large number of goroutines in a single program with modest memory usage.&lt;/p&gt;




&lt;h2&gt;
  
  
  Work Stealing Scheduler
&lt;/h2&gt;

&lt;p&gt;Go uses a work stealing scheduler.&lt;/p&gt;

&lt;p&gt;If one logical CPU runs out of work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It steals runnable goroutines from another CPUs queue&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This balances load across cores&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If no local work exists:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The scheduler checks a global queue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This keeps CPUs busy without manual tuning.&lt;/p&gt;




&lt;h2&gt;
  
  
  Blocking and System Calls
&lt;/h2&gt;

&lt;p&gt;When a goroutine performs a blocking system call:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The OS blocks the thread&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The runtime detaches other goroutines&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another thread takes over execution&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some operations, like network polling, use dedicated threads. This reduces unnecessary thread parking.&lt;/p&gt;

&lt;p&gt;The result:&lt;/p&gt;

&lt;p&gt;You write code that looks synchronous.&lt;br&gt;&lt;br&gt;
The runtime handles concurrency and scheduling.&lt;/p&gt;


&lt;h2&gt;
  
  
  Fork Join Model in Go
&lt;/h2&gt;

&lt;p&gt;Go follows the fork join idea.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The parent goroutine spawns child goroutines&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Child goroutines run concurrently&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After execution each child joins back with the parent using synchronization primitives like &lt;code&gt;WaitGroup&lt;/code&gt; or &lt;code&gt;channels&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;speak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;speak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If main exits early, the program terminates before the child goroutine finishes. You must coordinate execution.&lt;/p&gt;

&lt;p&gt;Goroutines share can memory and communicate, but in that case They must synchronize access using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Channels&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mutexes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Atomic operations&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ignoring synchronization can leads to race conditions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Process&lt;/th&gt;
&lt;th&gt;Thread&lt;/th&gt;
&lt;th&gt;Goroutine&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Memory&lt;/td&gt;
&lt;td&gt;Own memory space&lt;/td&gt;
&lt;td&gt;Shared memory within process&lt;/td&gt;
&lt;td&gt;Managed within process memory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Isolation&lt;/td&gt;
&lt;td&gt;Strong isolation&lt;/td&gt;
&lt;td&gt;No isolation within process&lt;/td&gt;
&lt;td&gt;No isolation within process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weight&lt;/td&gt;
&lt;td&gt;Heavyweight&lt;/td&gt;
&lt;td&gt;Lighter than process&lt;/td&gt;
&lt;td&gt;Very lightweight&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Context Switching&lt;/td&gt;
&lt;td&gt;Expensive&lt;/td&gt;
&lt;td&gt;Faster than process&lt;/td&gt;
&lt;td&gt;Very fast, user-space scheduled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Management&lt;/td&gt;
&lt;td&gt;OS managed&lt;/td&gt;
&lt;td&gt;Kernel managed&lt;/td&gt;
&lt;td&gt;Go runtime managed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scheduling&lt;/td&gt;
&lt;td&gt;OS scheduler&lt;/td&gt;
&lt;td&gt;OS scheduler&lt;/td&gt;
&lt;td&gt;User-space scheduler (Go runtime)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blocking&lt;/td&gt;
&lt;td&gt;Blocks independently&lt;/td&gt;
&lt;td&gt;Can block OS thread&lt;/td&gt;
&lt;td&gt;Efficient blocking behavior&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Failure Impact&lt;/td&gt;
&lt;td&gt;Safe from other process crashes&lt;/td&gt;
&lt;td&gt;One bad thread can crash process&lt;/td&gt;
&lt;td&gt;One bad goroutine can crash process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Synchronization&lt;/td&gt;
&lt;td&gt;IPC required&lt;/td&gt;
&lt;td&gt;Shared memory requires sync&lt;/td&gt;
&lt;td&gt;Requires proper synchronization&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  When To Use What
&lt;/h2&gt;

&lt;p&gt;Use processes when the priority is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Strong isolation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Security boundaries&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Crash containment&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use threads when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You need shared memory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You operate outside Go&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You rely on OS level primitives&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use goroutines when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You build concurrent services in Go&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You need high concurrency with low overhead&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You want simple concurrency syntax&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you build network services, background workers, or streaming systems in Go, goroutines give you scale without thread explosion.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Takeaway
&lt;/h2&gt;

&lt;p&gt;A process isolates.&lt;br&gt;&lt;br&gt;
A thread executes inside a process.&lt;br&gt;&lt;br&gt;
A goroutine executes inside a thread but is managed by the Go runtime.&lt;/p&gt;

&lt;p&gt;Isolation decreases as you move down the stack and Efficiency increases.&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=4rLW7zg21gI&amp;amp;pp=ygUScHJvY2VzcyB2cyB0aHJlYWRz" rel="noopener noreferrer"&gt;ByteByte Go&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=5LfqrEGwDmE&amp;amp;pp=ygUVZ29yb3V0aW5lcyB2cyB0aHJlYWRz" rel="noopener noreferrer"&gt;AppliedGo&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.karanpratapsingh.com/courses/go/goroutines" rel="noopener noreferrer"&gt;Goroutines&lt;/a&gt; blog&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>process</category>
      <category>threads</category>
      <category>goroutines</category>
    </item>
    <item>
      <title>What Actually Happens When You Run a Program</title>
      <dc:creator>Anish Roy</dc:creator>
      <pubDate>Wed, 18 Feb 2026 18:03:47 +0000</pubDate>
      <link>https://dev.to/pshycodr/what-actually-happens-when-you-run-a-program-57g3</link>
      <guid>https://dev.to/pshycodr/what-actually-happens-when-you-run-a-program-57g3</guid>
      <description>&lt;p&gt;You type a command and press Enter. A program starts in milliseconds. Your operating system performs a long chain of controlled steps. These steps involve the shell, the kernel, the CPU scheduler, and memory management.&lt;/p&gt;

&lt;p&gt;This blog traces that journey from the first keystroke to active execution.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1. From Command to Process Creation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj0fzi0feuaglhhjdxvs6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj0fzi0feuaglhhjdxvs6.png" alt="Block diagram of process creation" width="730" height="590"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your shell reads your command and parses the text. The shell runs as a normal user process. After parsing, the shell requests the kernel to start a new program.&lt;/p&gt;

&lt;p&gt;The kernel performs few actions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Allocates a process structure in memory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assigns a unique PID or process ID&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Loads the executable file from disk&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maps code and data into virtual memory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Places the process in a ready queue&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The executable file contains machine instructions and metadata. The kernel loader maps these sections into the process address space. The process now exists but waits for CPU time.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2. User Mode and Kernel Mode
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fynwfuv2p9eyem6gyh7p8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fynwfuv2p9eyem6gyh7p8.png" alt="User mode and kernal mode" width="732" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Modern CPUs enforce privilege separation between User mode and Kernal mode.&lt;/p&gt;

&lt;p&gt;User mode runs application code. Hardware access stays restricted. Your program reads and writes memory only inside its own address space.&lt;/p&gt;

&lt;p&gt;Kernel mode holds full privileges. The kernel controls hardware, memory, and devices.&lt;/p&gt;

&lt;p&gt;When your program needs system resources, it performs a system call. A system call triggers a controlled switch into kernel mode. The kernel validates the request, performs the operation, and returns control to user mode.&lt;/p&gt;

&lt;p&gt;This boundary prevents faulty programs from corrupting the system.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3. fork and exec
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg9dlhjp7ia6zgtc0cco7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg9dlhjp7ia6zgtc0cco7.png" alt="fork and exec" width="629" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unix style systems use a two step model for launching programs.&lt;/p&gt;

&lt;p&gt;The fork operation creates a child process. The child receives a copy of the parent memory space and file descriptors. Both processes continue execution from the same point.&lt;/p&gt;

&lt;p&gt;The child then calls exec. Exec replaces the child memory with a new program image. The PID remains unchanged. Only the code and data change.&lt;/p&gt;

&lt;p&gt;Your shell follows this pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The shell calls fork&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The child process calls exec with your command&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The parent shell waits or continues based on job rules&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This model keeps process management simple and predictable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4. Process States and Scheduling
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7s4u1nzknf5goiuaxvag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7s4u1nzknf5goiuaxvag.png" alt="Process States and Scheduling" width="580" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each process moves through defined states:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;New → process gets created&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ready → process waits for CPU time&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Running → process executes on a core&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Waiting → process pauses for input or output&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Terminated → process exits&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The scheduler decides which ready process runs next through different CPU scheduling algorithms like FCFS, SJF, SRTF, Round Robin etc.&lt;br&gt;&lt;br&gt;
Most schedulers use priorities and time slices. A time slice limits how long a process runs before a switch.&lt;/p&gt;

&lt;p&gt;During a context switch, the kernel:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Saves CPU registers of the current process&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Loads registers of the next process&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Updates scheduling data&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rapid switching creates the illusion of parallel execution.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 5. How the OS Tracks Resources
&lt;/h2&gt;

&lt;p&gt;The kernel tracks every process with a process control block.&lt;/p&gt;

&lt;p&gt;This structure stores:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Scheduling information&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Memory mappings&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open file tables&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Accounting data&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Virtual memory gives each process an isolated address space. Page tables map virtual addresses to physical memory. The kernel enforces protection rules through these mappings.&lt;/p&gt;

&lt;p&gt;File descriptors connect processes to resources. Each descriptor points to a kernel table entry. This entry refers to files, devices, or pipes. The kernel manages permissions and reference counts.&lt;/p&gt;


&lt;h2&gt;
  
  
  Live Terminal Experiments
&lt;/h2&gt;

&lt;p&gt;You can observe these concepts with simple commands.&lt;/p&gt;

&lt;p&gt;Run this in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps aux
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You see a snapshot of active processes. Each line represents a kernel tracked process with CPU and memory usage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6urv6ozg12emde89zm9q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6urv6ozg12emde89zm9q.png" alt="ps aux command execution" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run this next:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;top
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This display updates in real time. You can watch processes change states as the scheduler rotates tasks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flin4f6bylfdodcdxwwns.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flin4f6bylfdodcdxwwns.png" alt="top command execution" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Start a long running program in one terminal. Observe it with &lt;code&gt;ps&lt;/code&gt; or &lt;code&gt;top&lt;/code&gt; in another terminal. Stop the program and watch the entry disappear.&lt;/p&gt;




&lt;p&gt;Every program you run triggers process creation, scheduling, and resource tracking in a tight loop. These steps happen constantly in the background and shape how your system behaves.&lt;/p&gt;

&lt;p&gt;The next time you press Enter in a terminal, you see more than a command. You see a full process lifecycle running under your control.&lt;/p&gt;

</description>
      <category>process</category>
      <category>thread</category>
      <category>cpu</category>
    </item>
  </channel>
</rss>
