<?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.us-east-2.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>I Built a Local Bill Scanner So My Friend Stops Typing Invoices Into Google Sheets</title>
      <dc:creator>Anish Roy</dc:creator>
      <pubDate>Mon, 05 Oct 2026 06:50:51 +0000</pubDate>
      <link>https://dev.to/pshycodr/i-built-a-local-bill-scanner-so-my-friend-stops-typing-invoices-into-google-sheets-2h1j</link>
      <guid>https://dev.to/pshycodr/i-built-a-local-bill-scanner-so-my-friend-stops-typing-invoices-into-google-sheets-2h1j</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;My friend Abhik runs a shop. Every invoice and receipt from other shops used to get typed by hand into a Google Sheet. Date, store, items, tax, total.&lt;/p&gt;

&lt;p&gt;Now he drops in photos of the bills and presses Scan. Each bill is read on his laptop, shown next to the original photo, and he fixes anything that's off. Only after he approves does it go to the Sheet.&lt;/p&gt;

&lt;p&gt;When I showed it to him, this is what he said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It's really helpful. What amazes me is that all of this runs at zero cost, completely on my own computer. None of my data goes to the cloud or to some unknown company. Everything stays with me.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/pshycodr/invoice-processing-pipeline" rel="noopener noreferrer"&gt;github.com/pshycodr/invoice-processing-pipeline&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;Everything runs through Ollama. GLM-OCR or RapidOCR reads the photo, then gemma3:1b turns the text into JSON.&lt;/p&gt;

&lt;p&gt;But a 1B model is bad at picking numbers. It kept reading HSN codes as prices. So plain rules now pick the total, date and store, and the model only handles items, category and payment method.&lt;/p&gt;

&lt;p&gt;If OCR fails, the bill is marked handwritten, or no items are found, qwen3-vl:4b reads the image directly. Nothing reaches the Sheet without his approval.&lt;/p&gt;

&lt;p&gt;The page lets him pick the OCR engine, pick any Ollama model by name, and add his own categories.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;These are his suppliers' invoices, with prices and tax numbers. With open models that data never leaves his computer, and each bill costs nothing.&lt;/p&gt;

&lt;p&gt;Same idea as a cache with a slow path. The cheap OCR plus small model handles most bills, the vision model only runs on a miss, and he checks the final answer.&lt;/p&gt;

&lt;h1&gt;
  
  
  hacktoberfest #ollama #opensource
&lt;/h1&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
    </item>
    <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>
