Skip to Content
Go Realm v1 is released 🎉
Go Routines🧭 Day 1

🧠 Day 1: Go Concurrency Foundations & Goroutines

āĻāχ āĻĒā§āϰāĻĨāĻŽ āĻĻāĻŋāύ⧇ āϤ⧁āĻŽāĻŋ āĻļāĻŋāĻ–āĻŦ⧇ GoLang āĻ•āύāĻ•āĻžāϰ⧇āĻ¨ā§āϏāĻŋāϰ (Concurrency) āφāϏāϞ āĻļāĻ•ā§āϤāĻŋ — GoroutineāĨ¤ āφāĻŽāϰāĻž āϧāĻžāĻĒ⧇ āϧāĻžāĻĒ⧇ āĻļāĻŋāĻ–āĻŦ āϕ⧀āĻ­āĻžāĻŦ⧇ GoLang āĻāĻ•āϏāĻžāĻĨ⧇ āĻ…āύ⧇āĻ• āĻ•āĻžāϜ āĻĒāϰāĻŋāϚāĻžāϞāύāĻž āĻ•āϰ⧇, āϕ⧀āĻ­āĻžāĻŦ⧇ Goroutine āĻ•āĻžāϜ āĻ•āϰ⧇, āφāϰ āϕ⧇āύ āĻāϗ⧁āϞ⧋ āĻāϤ āĻĻā§āϰ⧁āϤ āĻ“ āϞāĻžāχāϟāĻ“āϝāĻŧ⧇āϟāĨ¤


đŸŽ¯ āφāϜāϕ⧇āϰ āϞāĻ•ā§āĻˇā§āϝ

  1. Concurrency āĻ“ Parallelism āĻāϰ āĻŽāĻ§ā§āϝ⧇ āĻĒāĻžāĻ°ā§āĻĨāĻ•ā§āϝ āĻĒ⧁āϰ⧋āĻĒ⧁āϰāĻŋ āĻŦā§‹āĻāĻž
  2. Goroutine āĻāϰ āĻ­āĻŋāϤāϰ⧇āϰ āĻŽā§‡āĻ•āĻžāύāĻŋāϜāĻŽ āĻļ⧇āĻ–āĻž
  3. Go Scheduler (M-P-G Model) āĻāϰ āĻ•āĻžāϜ āĻŦā§‹āĻāĻž
  4. āϕ⧇āύ Goroutine “Lightweight Thread” āĻŦāϞāĻž āĻšā§Ÿ
  5. Stack Management, Preemption, Scheduling Cycle āĻŦā§‹āĻāĻž
  6. āϕ⧇āύ main āĻĢāĻžāĻ‚āĻļāύ āĻļ⧇āώ āĻšāϞ⧇ Goroutine āϗ⧁āϞ⧋āĻ“ āĻŦāĻ¨ā§āϧ āĻšā§Ÿā§‡ āϝāĻžā§Ÿ — āϏ⧇āϟāĻž āĻĻ⧇āĻ–āĻžāĨ¤
  7. Runtime Behavior, Memory Cost, Performance Insight āĻŦā§‹āĻāĻž

🧩 ā§§. Concurrency vs Parallelism — āĻŽā§‚āϞ āĻ­āĻŋāĻ¤ā§āϤāĻŋ

āϧāĻžāϰāĻŖāĻžConcurrencyParallelism
āĻ…āĻ°ā§āĻĨāĻāĻ•āϏāĻžāĻĨ⧇ āĻ…āύ⧇āĻ• āĻ•āĻžāϜ āĻĒāϰāĻŋāϚāĻžāϞāύāĻž āĻ•āϰāĻžāĻāĻ•āϏāĻžāĻĨ⧇ āĻ…āύ⧇āĻ• āĻ•āĻžāϜ āϚāĻžāϞāĻžāύ⧋
āϕ⧋āϰ āĻŦā§āϝāĻŦāĻšāĻžāϰāĻāĻ• āϕ⧋āϰ⧇āĻ“ āϏāĻŽā§āĻ­āĻŦāĻāĻ•āĻžāϧāĻŋāĻ• āϕ⧋āϰ āϞāĻžāϗ⧇
āωāĻĻā§āĻĻ⧇āĻļā§āϝāϕ⧋āĻĄāϕ⧇ responsive āϰāĻžāĻ–āĻžāĻĒāĻžāϰāĻĢāϰāĻŽā§āϝāĻžāĻ¨ā§āϏ āĻŦāĻžā§œāĻžāύ⧋
āωāĻĻāĻžāĻšāϰāĻŖāĻāĻ•āϜāύ āϰāĻžāρāϧ⧁āύāĻŋ ā§ŠāϟāĻž āĻĒāĻĻ āĻāĻ•āϏāĻžāĻĨ⧇ āϤ⧈āϰāĻŋ āĻ•āϰāϛ⧇, āĻāĻ•āϟāĻžāϰ āĻ•āĻžāϜ āĻ•āϰ⧇ āφāϰ⧇āĻ•āϟāĻžā§Ÿ āϝāĻžāĻšā§āĻ›ā§‡ā§ŠāϜāύ āϰāĻžāρāϧ⧁āύāĻŋ ā§ŠāϟāĻž āĻĒāĻĻ āĻāĻ•āϏāĻžāĻĨ⧇ āϤ⧈āϰāĻŋ āĻ•āϰāϛ⧇
Go āϤ⧇goroutine switchinggoroutine āϗ⧁āϞ⧋ āφāϞāĻžāĻĻāĻž CPU core āĻ parallel āϚāϞāϛ⧇

🔹 Concurrency = Structure of doing multiple tasks 🔹 Parallelism = Execution of those tasks together

Go Concurrent design follow āĻ•āϰ⧇ → āϤāĻžāχ multi-core āĻ parallel run āĻ•āϰāϤ⧇ āĻ“ āϏāĻ•ā§āώāĻŽāĨ¤

Go āĻŽā§‚āϞāϤ Concurrent-first language, āĻŽāĻžāύ⧇ āĻāϟāĻŋ āĻāĻŽāύāĻ­āĻžāĻŦ⧇ āĻĄāĻŋāϜāĻžāχāύ āĻ•āϰāĻž āĻšā§Ÿā§‡āϛ⧇ āϝāĻžāϤ⧇ āϤ⧁āĻŽāĻŋ āĻ•āĻžāϜāϗ⧁āϞ⧋āϕ⧇ āϏ⧁āĻ¨ā§āĻĻāϰāĻ­āĻžāĻŦ⧇ āĻ­āĻžāĻ— āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧋, āĻĒāϰ⧇ runtime āϚāĻžāχāϞ⧇ āĻāϕ⧇ parallel āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇āĨ¤


🧩 ⧍. Goroutine — Go āϰ Concurrency āĻāϰ āĻšā§ƒāĻĻāĻĒāĻŋāĻŖā§āĻĄ

Goroutine āĻšāϞ⧋ Go-āĻāϰ concurrency-āĻāϰ āϏāĻŦāĻšā§‡ā§Ÿā§‡ āϗ⧁āϰ⧁āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖ āχāωāύāĻŋāϟāĨ¤ āĻāϟāĻŋ āĻšāϞ⧋ āĻāĻ•āϧāϰāύ⧇āϰ “āϞāĻžāχāϟāĻ“ā§Ÿā§‡āϟ āĻĨā§āϰ⧇āĻĄâ€ āϝāĻž Go runtime āύāĻŋāĻœā§‡ āϤ⧈āϰāĻŋ, āĻŽā§āϝāĻžāύ⧇āϜ, āĻāĻŦāĻ‚ schedule āĻ•āϰ⧇āĨ¤

āϤ⧁āĻŽāĻŋ āϝ⧇āĻ­āĻžāĻŦ⧇ āύāϤ⧁āύ Goroutine āĻļ⧁āϰ⧁ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧋:

go myFunction()

āĻāϤ⧇ runtime āĻāĻ•āϟāĻŋ āύāϤ⧁āύ goroutine āϤ⧈āϰāĻŋ āĻ•āϰ⧇, āϝāĻžāϰ āύāĻŋāϜāĻ¸ā§āĻŦ:

  • āϛ⧋āϟ stack (~2 KB āĻĨ⧇āϕ⧇ āĻļ⧁āϰ⧁)
  • scheduling data (āϕ⧋āĻĨāĻžā§Ÿ āϚāϞāϛ⧇, ready/blocked āχāĻ¤ā§āϝāĻžāĻĻāĻŋ)
  • heap shared with others (āϏāĻŦ goroutine āĻāĻ•āχ heap use āĻ•āϰ⧇)

🧠 āĻŽāύ⧇ āϰāĻžāĻ–ā§‹:

  • Go āϤ⧇ āϏāĻŦāĻ•āĻŋāϛ⧁ Goroutine — main() āύāĻŋāĻœā§‡āĻ“ āĻāĻ•āϟāĻŋ goroutineāĨ¤
  • Go runtime goroutine āĻĻ⧇āϰ OS thread āĻāϰ āωāĻĒāϰ āĻŽā§āϝāĻžāύ⧇āϜ āĻ•āϰ⧇āĨ¤

āĻāĻ•āĻĻāĻŽ āĻ āĻŋāĻ• āĻŦāϞ⧇āϛ⧋ 👍 — M-P-G model āĻĒā§āϰāĻĨāĻŽā§‡ āĻāĻ•āϟ⧁ āϜāϟāĻŋāϞ āĻŽāύ⧇ āĻšā§Ÿ, āĻ•āĻŋāĻ¨ā§āϤ⧁ āϏāĻšāϜ āωāĻĻāĻžāĻšāϰāĻŖ āφāϰ āϤ⧁āϞāύāĻž āĻĻāĻŋāϞ⧇ āĻŦāĻŋāώ⧟āϟāĻž āĻāĻ•āĻĻāĻŽ āĻĒāϰāĻŋāĻˇā§āĻ•āĻžāϰ āĻšā§Ÿā§‡ āϝāĻžā§ŸāĨ¤ āύāĻŋāĻšā§‡ āφāĻŽāĻŋ āϤ⧋āĻŽāĻžāϰ āĻ…āĻ‚āĻļāϟāĻž āϖ⧁āĻŦ āϏāĻšāϜ āĻ­āĻžāώāĻžā§Ÿ, āωāĻĻāĻžāĻšāϰāĻŖāϏāĻš āϞāĻŋāϖ⧇ āĻĻāĻŋāϞāĻžāĻŽ 👇


🧩 ā§Šī¸. Go Runtime Scheduler (M–P–G Model āϏāĻšāϜāĻ­āĻžāĻŦ⧇)

  • Go āĻāϰ āĻŽāĻ§ā§āϝ⧇ āĻāĻ•āϟāĻŋ āύāĻŋāϜāĻ¸ā§āĻŦ “mini manager” āφāϛ⧇, āϝāĻžāϕ⧇ āĻŦāϞ⧇ SchedulerāĨ¤
  • āĻāχ scheduler āĻ āĻŋāĻ• āĻ•āϰ⧇ āϕ⧋āύ goroutine āĻ•āĻ–āύ, āϕ⧋āύ CPU core āĻ āϚāϞāĻŦ⧇āĨ¤

âš™ī¸ āϤāĻŋāύāϟāĻŋ āĻ…āĻ‚āĻļ

āύāĻžāĻŽāĻĒ⧁āϰ⧋ āĻ…āĻ°ā§āĻĨāĻ•āĻžāϜ
GGoroutineāφāĻŽāĻžāĻĻ⧇āϰ āϕ⧋āĻĄ āĻŦāĻž āĻ•āĻžāϜ (āϝāĻž run āĻšāĻŦ⧇)
MMachineāφāϏāϞ OS thread (āϝ⧇āϟāĻž CPU āϤ⧇ āϚāϞ⧇)
PProcessorGoroutine āϗ⧁āϞ⧋āϕ⧇ āϏāĻžāϜāĻŋā§Ÿā§‡ āϰāĻžāϖ⧇ āĻāĻŦāĻ‚ M āĻāϰ āϏāĻžāĻĨ⧇ āϝ⧁āĻ•ā§āϤ āĻ•āϰ⧇

đŸŽŦ āϏāĻšāϜ āωāĻĻāĻžāĻšāϰāĻŖ

āϧāϰ⧋ āϤ⧁āĻŽāĻŋ āĻāĻ•āϜāύ āϰ⧇āĻ¸ā§āϟ⧁āϰ⧇āĻ¨ā§āϟ āĻŽā§āϝāĻžāύ⧇āϜāĻžāϰ:

  • đŸŊī¸ Goroutine (G) = āĻ…āύ⧇āĻ•āϗ⧁āϞ⧋ āĻ…āĻ°ā§āĻĄāĻžāϰ (āĻĒā§āϰāϤāĻŋāϟāĻŋ āϰāĻžāĻ¨ā§āύāĻž āφāϞāĻžāĻĻāĻž āĻ•āĻžāϜ)
  • đŸ‘¨â€đŸŗ Processor (P) = āĻāĻ•āϜāύ āĻļ⧇āĻĢ⧇āϰ āϏāĻšāĻ•āĻžāϰ⧀, āϝāĻŋāύāĻŋ āĻ…āĻ°ā§āĻĄāĻžāϰ āϏāĻžāϜāĻŋā§Ÿā§‡ āĻĻ⧇āύ
  • 🔧 Machine (M) = āφāϏāϞ āĻļ⧇āĻĢ, āϝāĻŋāύāĻŋ āϰāĻžāĻ¨ā§āύāĻž āĻ•āϰ⧇āύ (CPU thread)

āϤ⧁āĻŽāĻŋ (Scheduler) āĻĻ⧇āĻ–āϛ⧋ āϝ⧇āύ āĻļ⧇āĻĢ (M) āĻ…āϞāϏ āύāĻž āĻĨāĻžāϕ⧇ — āϤāĻžāχ āϤ⧁āĻŽāĻŋ P āĻāϰ queue āĻĨ⧇āϕ⧇ āĻ…āĻ°ā§āĻĄāĻžāϰ (G) āύāĻŋā§Ÿā§‡ āϤāĻžāϕ⧇ āĻĻāĻŋāĻšā§āϛ⧋āĨ¤

āϝāĻĻāĻŋ āĻāĻ• āĻļ⧇āĻĢ⧇āϰ āϏāĻŦ āĻ…āĻ°ā§āĻĄāĻžāϰ āĻļ⧇āώ āĻšā§Ÿā§‡ āϝāĻžā§Ÿ, āϏ⧇ āĻ…āĻ¨ā§āϝ āĻļ⧇āĻĢ⧇āϰ āϏāĻšāĻ•āĻžāϰ⧀āϰ āĻ•āĻžāĻ› āĻĨ⧇āϕ⧇ āĻ…āĻ°ā§āĻĄāĻžāϰ “āϚ⧁āϰāĻŋ” āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇ (āĻāϟāĻžāχ work stealing) 😄


🔄 āĻ•āĻžāĻœā§‡āϰ āϧāĻžāĻĒ

  1. āĻĒā§āϰāϤāĻŋāϟāĻŋ P āĻāϰ āĻāĻ•āϟāĻŋ āϛ⧋āϟ queue āĻĨāĻžāϕ⧇ āϝ⧇āĻ–āĻžāύ⧇ goroutine āϗ⧁āϞ⧋ āĻ…āĻĒ⧇āĻ•ā§āώāĻž āĻ•āϰ⧇āĨ¤
  2. āϕ⧋āύ⧋ M (thread) āĻĢāĻžāρāĻ•āĻž āĻĨāĻžāĻ•āϞ⧇, P āϤāĻžāϕ⧇ āĻ•āĻžāϜ āĻĻā§‡ā§ŸāĨ¤
  3. GOMAXPROCS āύāĻŋāĻ°ā§āϧāĻžāϰāĻŖ āĻ•āϰ⧇ āĻ•ā§ŸāϟāĻž P (logical core) āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻšāĻŦ⧇āĨ¤
  4. āϝāĻĻāĻŋ āϕ⧋āύ⧋ goroutine āĻŦā§āϞāĻ• āĻšā§Ÿ (āϝ⧇āĻŽāύ I/O), scheduler āϏāĻžāĻĨ⧇ āϏāĻžāĻĨ⧇ āĻ…āĻ¨ā§āϝāϟāĻž āϚāĻžāϞāĻžā§ŸāĨ¤

âš™ī¸ M:N Scheduling āĻŽāĻžāύ⧇ āϕ⧀

Go runtime āĻ…āύ⧇āĻ•āϗ⧁āϞ⧋ (N) goroutine āϕ⧇ āĻ•āĻŽ āϏāĻ‚āĻ–ā§āϝāĻ• (M) OS thread-āĻāϰ āωāĻĒāϰ āϚāĻžāϞāĻžā§ŸāĨ¤

🧠 āĻŽāĻžāύ⧇ — āĻšāĻžāϜāĻžāϰ āĻšāĻžāϜāĻžāϰ goroutine āϚāϞāĻŦ⧇, āĻ•āĻŋāĻ¨ā§āϤ⧁ CPU thread āϞāĻžāĻ—āĻŦ⧇ āϖ⧁āĻŦ āĻ•āĻŽ!


🌀 Work Stealing (āϏāĻšāϜāĻ­āĻžāĻŦ⧇)

āϝāĻĻāĻŋ āϕ⧋āύ⧋ processor-āĻāϰ queue āĻĢāĻžāρāĻ•āĻž āĻĨāĻžāϕ⧇, āϏ⧇ āĻ…āĻ¨ā§āϝ processor-āĻāϰ queue āĻĨ⧇āϕ⧇ goroutine āύāĻŋā§Ÿā§‡ āĻ¨ā§‡ā§ŸāĨ¤

👉 āĻāϤ⧇ CPU āĻ•āĻ–āύ⧋ āĻĢāĻžāρāĻ•āĻž āĻŦāϏ⧇ āĻĨāĻžāϕ⧇ āύāĻž, āϏāĻŦāϏāĻŽā§Ÿ āĻŦā§āϝāĻ¸ā§āϤ āĻĨāĻžāϕ⧇āĨ¤


✅ āϏāĻ‚āĻ•ā§āώāĻŋāĻĒā§āϤ āϏāĻžāϰāĻžāĻ‚āĻļ

āĻĒā§Ÿā§‡āĻ¨ā§āϟāϏāĻšāϜ āĻŦā§āϝāĻžāĻ–ā§āϝāĻž
Goroutine (G)āĻ•āĻžāϜ āĻ•āϰāĻžāϰ āχāωāύāĻŋāϟ
Processor (P)āĻ•āĻžāϜ āϏāĻžāϜāĻžā§Ÿ āĻāĻŦāĻ‚ thread-āĻāϰ āϏāĻžāĻĨ⧇ bind āĻ•āϰ⧇
Machine (M)CPU-āϤ⧇ āϚāϞāĻž āφāϏāϞ thread
SchedulerāϏāĻŦ āĻ•āĻŋāϛ⧁ manage āĻ•āϰ⧇
GOMAXPROCSāĻ•ā§ŸāϟāĻž CPU core āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻšāĻŦ⧇ āύāĻŋāĻ°ā§āϧāĻžāϰāĻŖ āĻ•āϰ⧇
Work Stealingidle CPU āĻ…āĻ¨ā§āϝāĻĻ⧇āϰ āĻ•āĻžāϜ āύāĻŋā§Ÿā§‡ āĻ¨ā§‡ā§Ÿ

🧩 āĻšā§‹āϖ⧇ āĻĻ⧇āĻ–āĻž āϛ⧋āϟ āĻĄāĻžāϝāĻŧāĻžāĻ—ā§āϰāĻžāĻŽ

G1, G2, G3 → [P1] → [M1] G4, G5, G6 → [P2] → [M2]

āϝāĻĻāĻŋ P1 āĻāϰ queue āĻĢāĻžāρāĻ•āĻž āĻšā§Ÿ, āϏ⧇ P2 āĻĨ⧇āϕ⧇ G āϚ⧁āϰāĻŋ āĻ•āϰāϤ⧇ āĻĒāĻžāϰ⧇ 🌀


🧩 ā§Ē. Lightweight Thread āĻŽāĻžāύ⧇ āϕ⧀?

Goroutine-āϕ⧇ āĻŦāϞāĻž āĻšā§Ÿ “Lightweight Thread”, āĻ•āĻžāϰāĻŖ āĻāϟāĻŋ āϏāĻžāϧāĻžāϰāĻŖ OS thread-āĻāϰ āϤ⧁āϞāύāĻžā§Ÿ āĻ…āύ⧇āĻ• āĻšāĻžāϞāĻ•āĻž, āĻĻā§āϰ⧁āϤ, āĻāĻŦāĻ‚ āĻ•āĻŽ āĻŽā§‡āĻŽāϰāĻŋ-āĻŦā§āĻ¯ā§Ÿā§€āĨ¤ Go runtime āύāĻŋāĻœā§‡āχ āĻāϗ⧁āϞ⧋ āϤ⧈āϰāĻŋ āĻ“ āύāĻŋ⧟āĻ¨ā§āĻ¤ā§āϰāĻŖ āĻ•āϰ⧇, āϤāĻžāχ OS kernel-āϕ⧇ āϘāύāϘāύ āĻĄāĻžāĻ•āĻžāϰ āĻĻāϰāĻ•āĻžāϰ āĻšā§Ÿ āύāĻžāĨ¤

āĻŦāĻŋāώ⧟OS ThreadGoroutine
Stack Size~1MB āĻĨ⧇āϕ⧇ 2MB (fixed)āĻŽāĻžāĻ¤ā§āϰ ~2KB āĻĨ⧇āϕ⧇ āĻļ⧁āϰ⧁ āĻšā§Ÿ āĻāĻŦāĻ‚ āĻĒā§āĻ°ā§Ÿā§‹āϜāύ āĻ…āύ⧁āϝāĻžā§Ÿā§€ āĻŦāĻžā§œā§‡ āĻŦāĻž āĻ•āĻŽā§‡ (dynamic growth)
Managed ByOS kernelGo runtime (user-space)
Context SwitchSlow (Kernel-level)Fast (User-space)
Creation TimeSlow (āĻ…āύ⧇āĻ• āĻŦ⧇āĻļāĻŋ)Fast (microseconds level) (āĻ…āύ⧇āĻ• āĻ•āĻŽ āϏāĻŽāϝāĻŧ)
Typical CountāϏāĻžāϧāĻžāϰāĻŖāϤ āĻ•ā§Ÿā§‡āĻ• āĻšāĻžāϜāĻžāϰ āĻĒāĻ°ā§āϝāĻ¨ā§āϤ āϏāĻŽā§āĻ­āĻŦāϞāĻ•ā§āώāĻžāϧāĻŋāĻ• goroutine āĻāĻ•āϏāĻžāĻĨ⧇ āϚāϞāϤ⧇ āĻĒāĻžāϰ⧇

💡 āϕ⧇āύ Lightweight āĻŦāϞāĻž āĻšā§Ÿ?

Goroutine āĻšāĻžāϞāĻ•āĻž āĻšāĻ“ā§ŸāĻžāϰ āĻĒā§āϰāϧāĻžāύ āĻ•āĻžāϰāĻŖāϗ⧁āϞ⧋:

  • Dynamic Stack
  • Context switch kernel-level āύ⧟ → āϤāĻžāχ āĻ…āύ⧇āĻ• āĻĻā§āϰ⧁āϤ
  • Long-running goroutine āϕ⧇ runtime āĻœā§‹āϰ āĻ•āϰ⧇ āĻĨāĻžāĻŽāĻŋā§Ÿā§‡ āĻ…āĻ¨ā§āϝ goroutine āϕ⧇ āϚāĻžāϞāĻžāϤ⧇ āĻĒāĻžāϰ⧇
  • āĻĢāϞ⧇ starvation āĻŦāĻž hang āĻšā§Ÿ āύāĻž

🧩 ā§Ģī¸. Stack Growth Mechanism

  • āĻĒā§āϰāϤāĻŋāϟāĻŋ Goroutine āĻĒā§āϰāĻžā§Ÿ ⧍KB stack āĻĻāĻŋā§Ÿā§‡ āĻļ⧁āϰ⧁ āĻšā§ŸāĨ¤
  • āϝāĻ–āύ function call depth āĻŦāĻžā§œā§‡ → Go runtime āĻ¸ā§āĻŦ⧟āĻ‚āĻ•ā§āϰāĻŋ⧟āĻ­āĻžāĻŦ⧇ stack āĻŦ⧜ āĻ•āϰ⧇ āĻĢ⧇āϞ⧇
  • āφāϰ āĻ•āĻžāϜ āĻļ⧇āώ āĻšāϞ⧇ āφāĻŦāĻžāϰ āϛ⧋āϟ āĻ•āϰ⧇ āĻĢ⧇āϞ⧇āĨ¤
  • stack growth āĻāĻŦāĻ‚ shrink āĻĻ⧁āĻŸā§‹āχ safe āĻ“ automatic

âžĄī¸ āĻĢāϞ: āϤ⧁āĻŽāĻŋ āϞāĻžāĻ– go routine āϤ⧈āϰāĻŋ āĻ•āϰāϞ⧇āĻ“ out of memory āĻšāĻŦ⧇ āύāĻžāĨ¤


🧩 ā§Ŧī¸. āϕ⧇āύ Goroutine āĻāϤ āϏāĻ¸ā§āϤāĻž (Cheap)

✅ āϛ⧋āϟ Stack → Memory āĻ•āĻŽ āϞāĻžāϗ⧇ ✅ User-space Scheduler → Kernel-āĻ āĻŦāĻžāϰāĻŦāĻžāϰ āϝ⧇āϤ⧇ āĻšā§Ÿ āύāĻž ✅ Auto Load Balancing → Scheduler āύāĻŋāĻœā§‡āχ CPU āϗ⧁āϞ⧋āϤ⧇ āĻ•āĻžāϜ āĻ­āĻžāĻ— āĻ•āϰ⧇ āĻĻā§‡ā§Ÿ ✅ Communication Mechanism (Channels) → Safe data sharing

👉 āĻĢāϞāĻžāĻĢāϞ: āϤ⧁āĻŽāĻŋ āϚāĻžāχāϞ⧇ ā§§ āϞāĻžāĻ–+ Goroutine āϤ⧈āϰāĻŋ āĻ•āϰāϤ⧇ āĻĒāĻžāϰāĻŦ⧇ āĻāĻŦāĻ‚ āϤāĻžāĻ“ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽ āĻ āĻŋāĻ•āĻ āĻžāĻ• āϚāϞāĻŦ⧇āĨ¤


🧩 ā§­ī¸. Goroutine Lifecycle

New → Runnable → Running → Waiting → Runnable → Dead
  • New: just created, not yet scheduled
  • Runnable: ready queue āϤ⧇ āĻ…āĻĒ⧇āĻ•ā§āώāĻž āĻ•āϰ⧇
  • Running: currently executing
  • Waiting: I/O āĻŦāĻž channel āĻāϰ āϜāĻ¨ā§āϝ āĻŦā§āϞāĻ•āĻĄ
  • Dead: execution āĻļ⧇āώ

Go runtime āĻ āĻĒā§āϰāϤāĻŋ P āĻāϰ queue āĻĨāĻžāϕ⧇ āϝ⧇āĻ–āĻžāύ⧇ Runnable goroutine āĻĨāĻžāϕ⧇āĨ¤


🧩 ā§Žī¸. main() āĻļ⧇āώ āĻšāϞ⧇ āϕ⧀ āĻšā§Ÿ

  • Go āϤ⧇ main() āύāĻŋāĻœā§‡āχ āĻāĻ•āϟāĻŋ Goroutine (main Goroutine)āĨ¤
  • main() āĻļ⧇āώ āĻšāϞ⧇ program terminate āĻšā§Ÿā§‡ āϝāĻžā§Ÿ, āĻ…āĻ¨ā§āϝ goroutine kill āĻšā§Ÿā§‡ āϝāĻžā§ŸāĨ¤

đŸ’ģ Hands-On Exercises

1ī¸âƒŖ Simple Goroutine

package main import ( "fmt" "time" ) func main() { go func() { fmt.Println("Hello Goroutine!") }() time.Sleep(50 * time.Millisecond) fmt.Println("Main done") }

🧩 Try removing time.Sleep() — you’ll likely not see “Hello, Goroutine!” because the main Goroutine ends first.

2ī¸âƒŖ Multiple Goroutines

package main import ( "fmt" "time" ) func printMsg(msg string) { fmt.Println(msg) } func main() { go printMsg("Alpha") go printMsg("Beta") go printMsg("Gamma") time.Sleep(100 * time.Millisecond) fmt.Println("Main exiting") }

Run it several times — you’ll see the output order change. That’s because Goroutines run concurrently; the scheduler decides their order.

3ī¸âƒŖ Demonstrate Main Exit

func main() { go fmt.Println("A") go fmt.Println("B") go fmt.Println("C") }

Output: → often nothing prints, because main exits immediately.


🧠 āύāĻŋāĻœā§‡ āĻ­āĻžāĻŦā§‹

  1. Concurrency vs Parallelism āĻāϰ āĻŽā§‚āϞ āĻĒāĻžāĻ°ā§āĻĨāĻ•ā§āϝ āĻ•āĻŋ?
  2. āϕ⧇āύ Goroutine lightweight?
  3. M-P-G āĻŽāĻĄā§‡āϞ āĻāϰ āĻ­ā§‚āĻŽāĻŋāĻ•āĻž āĻ•āĻŋ?
  4. Stack growth āϕ⧇āύ important?
  5. main() āĻļ⧇āώ āĻšāϞ⧇ program āϕ⧇āύ terminate āĻšā§Ÿ?
  6. Preemption āϕ⧀āĻ­āĻžāĻŦ⧇ scheduler āϕ⧇ āϏāĻšāĻžā§ŸāϤāĻž āĻ•āϰ⧇?

🧾 āϏāĻžāϰāϏāĻ‚āĻ•ā§āώ⧇āĻĒ

āϧāĻžāϰāĻŖāĻžāĻŽā§‚āϞ āĻĒā§Ÿā§‡āĻ¨ā§āϟ
Goroutineuser-space lightweight thread
SchedulerāĻ…āύ⧇āĻ• goroutine āϕ⧇ āĻ•āĻŽ āϏāĻ‚āĻ–ā§āϝāĻ• thread āĻ āĻŽā§āϝāĻžāĻĒ āĻ•āϰ⧇
Stack Managementāϛ⧋āϟ stack → auto grow/shrink
Preemptionscheduler āύāĻŋāĻœā§‡ context switch āĻ•āϰāĻžāϤ⧇ āĻĒāĻžāϰ⧇
EfficiencyāϞāĻ•ā§āώāĻžāϧāĻŋāĻ• goroutine āϏāĻšāĻœā§‡ manage āĻ•āϰ⧇
Exit Rulemain() āĻļ⧇āώ → āϏāĻŦ goroutine āĻļ⧇āώ

📚 āϰāĻŋāϏ⧋āĻ°ā§āϏ


🧩 Mini Challenge

āĻāĻ•āϟāĻž āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽ āϞāĻŋāĻ–ā§‹ āϝ⧇āϟāĻž:

  • ā§§ā§Ļā§Ļ āϟāĻž goroutine āϚāĻžāϞāĻžāĻŦ⧇
  • āĻĒā§āϰāĻ¤ā§āϝ⧇āϕ⧇ āύāĻŋāĻœā§‡āϰ āύāĻžāĻŽ āĻĒā§āϰāĻŋāĻ¨ā§āϟ āĻ•āϰāĻŦ⧇ (“Worker 1” āĻĨ⧇āϕ⧇ “Worker 100”)
  • main āĻĢāĻžāĻ‚āĻļāύ⧇ āĻāĻ•āϟāĻž sleep āĻĻāĻžāĻ“ āϝāĻžāϤ⧇ āϏāĻŦāϗ⧁āϞ⧋ āϚāĻžāϞāĻžāϤ⧇ āĻĒāĻžāϰ⧇
  • output order observe āĻ•āϰ⧋ (āĻĒā§āϰāϤāĻŋāĻŦāĻžāϰ āĻ­āĻŋāĻ¨ā§āύ āĻšāĻŦ⧇)

🧠 Deep Think Exercise

1ī¸âƒŖ āϤ⧁āĻŽāĻŋ Go runtime āĻšāĻŋāϏ⧇āĻŦ⧇ āĻ­āĻžāĻŦā§‹ — āϤ⧁āĻŽāĻŋ āϕ⧀āĻ­āĻžāĻŦ⧇ decide āĻ•āϰāĻŦ⧇ āϕ⧋āύ goroutine āφāϗ⧇ run āĻšāĻŦ⧇?

Go runtime āĻāϰ scheduler run queue āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻ•āϰ⧇ goroutine āϗ⧁āϞ⧋āϕ⧇ āĻŽā§āϝāĻžāύ⧇āϜ āĻ•āϰ⧇āĨ¤ āĻĒā§āϰāϤāĻŋāϟāĻŋ Processor (P)-āĻāϰ āύāĻŋāϜāĻ¸ā§āĻŦ queue āĻĨāĻžāϕ⧇āĨ¤ Scheduler FIFO (first in, first out) āύāĻŋ⧟āĻŽā§‡ goroutine āϚāĻžāϞāĻžā§ŸāĨ¤

āϤāĻŦ⧇ āϝāĻĻāĻŋ āϕ⧋āύ⧋ goroutine I/O āĻ•āϰ⧇ āĻŦāĻž āĻŦā§āϞāĻ• āĻšā§Ÿ, āϤāĻ–āύ scheduler āϏ⧇āϟāĻŋāϕ⧇ waiting state āĻ āĻĒāĻžāĻ āĻžā§Ÿ āĻāĻŦāĻ‚ āĻ…āĻ¨ā§āϝ ready goroutine āϕ⧇ CPU āĻĻā§‡ā§Ÿ — āĻāϤ⧇ āϕ⧋āύ⧋ goroutine āĻĻā§€āĻ°ā§āϘ āϏāĻŽā§Ÿ idle āĻĨāĻžāϕ⧇ āύāĻžāĨ¤


2ī¸âƒŖ āϝāĻĻāĻŋ āĻāĻ•āϟāĻž goroutine CPU-bound āĻĨāĻžāϕ⧇ (āϝ⧇āĻŽāύ infinite loop), āϤāĻžāĻšāϞ⧇ āĻ…āĻ¨ā§āϝ goroutine āĻ•āĻŋ āϚāϞāĻŦ⧇? (→ preemption)

āĻšā§āϝāĻžāρ, āĻāĻ–āύ Go 1.14+ āĻĨ⧇āϕ⧇ asynchronous preemption āφāϛ⧇āĨ¤ Scheduler āĻĻā§€āĻ°ā§āϘ āϏāĻŽā§Ÿ āϧāϰ⧇ āϚāϞāĻž (CPU-bound) goroutine āϕ⧇ āĻœā§‹āϰ āĻ•āϰ⧇ āĻĨāĻžāĻŽāĻŋā§Ÿā§‡ āĻĻā§‡ā§Ÿ āĻāĻŦāĻ‚ āĻ…āĻ¨ā§āϝ goroutine āϕ⧇ run āĻ•āϰāĻžāϰ āϏ⧁āϝ⧋āĻ— āĻĻā§‡ā§ŸāĨ¤

āĻāϰ āĻĢāϞ⧇ āϕ⧋āύ⧋ goroutine āĻĒ⧁āϰ⧋ CPU āĻĻāĻ–āϞ āĻ•āϰ⧇ āϰāĻžāĻ–āϤ⧇ āĻĒāĻžāϰ⧇ āύāĻžāĨ¤


3ī¸âƒŖ āĻāĻ• goroutine blocking I/O āĻ•āϰāϞ⧇ āĻ•āĻŋ āĻŦāĻžāĻ•āĻŋāϗ⧁āϞ⧋ āĻĨ⧇āĻŽā§‡ āϝāĻžā§Ÿ?

āύāĻž ❌

Go runtime āĻĒā§āϰāϤāĻŋāϟāĻŋ blocking call (āϝ⧇āĻŽāύ network, file I/O) āφāϞāĻžāĻĻāĻž OS thread-āĻ āĻĒāĻžāĻ āĻŋā§Ÿā§‡ āĻĻā§‡ā§ŸāĨ¤ āϤāĻ–āύ āϏ⧇āχ thread āĻŦā§āϞāĻ• āĻĨāĻžāĻ•āϞ⧇āĻ“ runtime āĻ…āĻ¨ā§āϝ goroutine āϗ⧁āϞ⧋āϕ⧇ āĻ…āĻ¨ā§āϝ thread (M) āĻĻāĻŋā§Ÿā§‡ āϚāĻžāϞāĻŋā§Ÿā§‡ āϝāĻžā§ŸāĨ¤

āĻĢāϞ⧇ I/O-bound goroutine āĻĨāĻžāĻŽāϞ⧇āĻ“ āĻĒ⧁āϰ⧋ āĻĒā§āϰ⧋āĻ—ā§āϰāĻžāĻŽ āĻŦā§āϞāĻ• āĻšā§Ÿ āύāĻžāĨ¤


4ī¸âƒŖ āϕ⧀āĻ­āĻžāĻŦ⧇ GOMAXPROCS runtime performance āĻĒā§āϰāĻ­āĻžāĻŦāĻŋāϤ āĻ•āϰ⧇?

GOMAXPROCS āύāĻŋāĻ°ā§āϧāĻžāϰāĻŖ āĻ•āϰ⧇ āĻāĻ•āϏāĻžāĻĨ⧇ āĻ•ā§ŸāϟāĻž OS thread (Processor P) CPU-āϤ⧇ active āĻĨāĻžāĻ•āĻŦ⧇āĨ¤

  • āϝāĻĻāĻŋ āĻāϟāĻž CPU core āϏāĻ‚āĻ–ā§āϝāĻžāϰ āϏāĻŽāĻžāύ āϰāĻžāĻ–āĻž āĻšā§Ÿ → performance optimal āĻšā§Ÿ 🧠
  • āϖ⧁āĻŦ āĻ•āĻŽ āĻĻāĻŋāϞ⧇ → CPU āĻĒ⧁āϰ⧋āĻĒ⧁āϰāĻŋ āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻšā§Ÿ āύāĻž (idle āĻĨāĻžāϕ⧇)
  • āϖ⧁āĻŦ āĻŦ⧇āĻļāĻŋ āĻĻāĻŋāϞ⧇ → context switching āĻŦā§‡ā§œā§‡ āϝāĻžā§Ÿ, performance āĻ•āĻŽā§‡

💡 āϏāĻžāϧāĻžāϰāĻŖāϤ runtime.GOMAXPROCS(runtime.NumCPU()) āϏāĻŦāĻšā§‡ā§Ÿā§‡ āĻ­āĻžāϞ⧋ āϏ⧇āϟāĻŋāĻ‚āĨ¤


🔮 Day 2 Preview: Channels

āĻĒāϰ⧇āϰ āĻĻāĻŋāύ āφāĻŽāϰāĻž āĻļāĻŋāĻ–āĻŦ Go āĻāϰ āϏāĻŦāĻšā§‡ā§Ÿā§‡ āĻŽā§āϝāĻžāϜāĻŋāĻ•āĻžāϞ āĻ…āĻ‚āĻļ — Channel — Goroutine āĻĻ⧇āϰ āĻŽāĻ§ā§āϝ⧇ āύāĻŋāϰāĻžāĻĒāĻĻ communication āĻāϰ āωāĻĒāĻžā§ŸāĨ¤ āφāĻŽāϰāĻž āĻĻ⧇āĻ–āĻŦ:

  • Unbuffered vs Buffered Channel
  • Data Synchronization
  • Channel blocking behavior
  • Deadlock avoidance pattern