đ§ Day 1: Go Concurrency Foundations & Goroutines
āĻāĻ āĻĒā§āϰāĻĨāĻŽ āĻĻāĻŋāύ⧠āϤā§āĻŽāĻŋ āĻļāĻŋāĻāĻŦā§ GoLang āĻāύāĻāĻžāϰā§āύā§āϏāĻŋāϰ (Concurrency) āĻāϏāϞ āĻļāĻā§āϤāĻŋ â GoroutineāĨ¤ āĻāĻŽāϰāĻž āϧāĻžāĻĒā§ āϧāĻžāĻĒā§ āĻļāĻŋāĻāĻŦ āĻā§āĻāĻžāĻŦā§ GoLang āĻāĻāϏāĻžāĻĨā§ āĻ āύā§āĻ āĻāĻžāĻ āĻĒāϰāĻŋāĻāĻžāϞāύāĻž āĻāϰā§, āĻā§āĻāĻžāĻŦā§ Goroutine āĻāĻžāĻ āĻāϰā§, āĻāϰ āĻā§āύ āĻāĻā§āϞ⧠āĻāϤ āĻĻā§āϰā§āϤ āĻ āϞāĻžāĻāĻāĻāϝāĻŧā§āĻāĨ¤
đ¯ āĻāĻāĻā§āϰ āϞāĻā§āώā§āϝ
- Concurrency āĻ Parallelism āĻāϰ āĻŽāϧā§āϝ⧠āĻĒāĻžāϰā§āĻĨāĻā§āϝ āĻĒā§āϰā§āĻĒā§āϰāĻŋ āĻŦā§āĻāĻž
- Goroutine āĻāϰ āĻāĻŋāϤāϰā§āϰ āĻŽā§āĻāĻžāύāĻŋāĻāĻŽ āĻļā§āĻāĻž
- Go Scheduler (M-P-G Model) āĻāϰ āĻāĻžāĻ āĻŦā§āĻāĻž
- āĻā§āύ Goroutine âLightweight Threadâ āĻŦāϞāĻž āĻšā§
- Stack Management, Preemption, Scheduling Cycle āĻŦā§āĻāĻž
- āĻā§āύ main āĻĢāĻžāĻāĻļāύ āĻļā§āώ āĻšāϞ⧠Goroutine āĻā§āϞā§āĻ āĻŦāύā§āϧ āĻšā§ā§ āϝāĻžā§ â āϏā§āĻāĻž āĻĻā§āĻāĻžāĨ¤
- Runtime Behavior, Memory Cost, Performance Insight āĻŦā§āĻāĻž
đ§Š ā§§. Concurrency vs Parallelism â āĻŽā§āϞ āĻāĻŋāϤā§āϤāĻŋ
| āϧāĻžāϰāĻŖāĻž | Concurrency | Parallelism |
|---|---|---|
| āĻ āϰā§āĻĨ | āĻāĻāϏāĻžāĻĨā§ āĻ āύā§āĻ āĻāĻžāĻ āĻĒāϰāĻŋāĻāĻžāϞāύāĻž āĻāϰāĻž | āĻāĻāϏāĻžāĻĨā§ āĻ āύā§āĻ āĻāĻžāĻ āĻāĻžāϞāĻžāύ⧠|
| āĻā§āϰ āĻŦā§āϝāĻŦāĻšāĻžāϰ | āĻāĻ āĻā§āϰā§āĻ āϏāĻŽā§āĻāĻŦ | āĻāĻāĻžāϧāĻŋāĻ āĻā§āϰ āϞāĻžāĻā§ |
| āĻāĻĻā§āĻĻā§āĻļā§āϝ | āĻā§āĻĄāĻā§ responsive āϰāĻžāĻāĻž | āĻĒāĻžāϰāĻĢāϰāĻŽā§āϝāĻžāύā§āϏ āĻŦāĻžā§āĻžāύ⧠|
| āĻāĻĻāĻžāĻšāϰāĻŖ | āĻāĻāĻāύ āϰāĻžāĻāϧā§āύāĻŋ ā§ŠāĻāĻž āĻĒāĻĻ āĻāĻāϏāĻžāĻĨā§ āϤā§āϰāĻŋ āĻāϰāĻā§, āĻāĻāĻāĻžāϰ āĻāĻžāĻ āĻāϰ⧠āĻāϰā§āĻāĻāĻžā§ āϝāĻžāĻā§āĻā§ | ā§ŠāĻāύ āϰāĻžāĻāϧā§āύāĻŋ ā§ŠāĻāĻž āĻĒāĻĻ āĻāĻāϏāĻžāĻĨā§ āϤā§āϰāĻŋ āĻāϰāĻā§ |
| Go āϤ⧠| goroutine switching | goroutine āĻā§āϞ⧠āĻāϞāĻžāĻĻāĻž 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 āĻ āĻāϞāĻŦā§āĨ¤
âī¸ āϤāĻŋāύāĻāĻŋ āĻ āĻāĻļ
| āύāĻžāĻŽ | āĻĒā§āϰ⧠āĻ āϰā§āĻĨ | āĻāĻžāĻ |
|---|---|---|
| G | Goroutine | āĻāĻŽāĻžāĻĻā§āϰ āĻā§āĻĄ āĻŦāĻž āĻāĻžāĻ (āϝāĻž run āĻšāĻŦā§) |
| M | Machine | āĻāϏāϞ OS thread (āϝā§āĻāĻž CPU āϤ⧠āĻāϞā§) |
| P | Processor | Goroutine āĻā§āϞā§āĻā§ āϏāĻžāĻāĻŋā§ā§ āϰāĻžāĻā§ āĻāĻŦāĻ M āĻāϰ āϏāĻžāĻĨā§ āϝā§āĻā§āϤ āĻāϰ⧠|
đŦ āϏāĻšāĻ āĻāĻĻāĻžāĻšāϰāĻŖ
āϧāϰ⧠āϤā§āĻŽāĻŋ āĻāĻāĻāύ āϰā§āϏā§āĻā§āϰā§āύā§āĻ āĻŽā§āϝāĻžāύā§āĻāĻžāϰ:
- đŊī¸ Goroutine (G) = āĻ āύā§āĻāĻā§āϞ⧠āĻ āϰā§āĻĄāĻžāϰ (āĻĒā§āϰāϤāĻŋāĻāĻŋ āϰāĻžāύā§āύāĻž āĻāϞāĻžāĻĻāĻž āĻāĻžāĻ)
- đ¨âđŗ Processor (P) = āĻāĻāĻāύ āĻļā§āĻĢā§āϰ āϏāĻšāĻāĻžāϰā§, āϝāĻŋāύāĻŋ āĻ āϰā§āĻĄāĻžāϰ āϏāĻžāĻāĻŋā§ā§ āĻĻā§āύ
- đ§ Machine (M) = āĻāϏāϞ āĻļā§āĻĢ, āϝāĻŋāύāĻŋ āϰāĻžāύā§āύāĻž āĻāϰā§āύ (CPU thread)
āϤā§āĻŽāĻŋ (Scheduler) āĻĻā§āĻāĻā§ āϝā§āύ āĻļā§āĻĢ (M) āĻ āϞāϏ āύāĻž āĻĨāĻžāĻā§ â āϤāĻžāĻ āϤā§āĻŽāĻŋ P āĻāϰ queue āĻĨā§āĻā§ āĻ āϰā§āĻĄāĻžāϰ (G) āύāĻŋā§ā§ āϤāĻžāĻā§ āĻĻāĻŋāĻā§āĻā§āĨ¤
āϝāĻĻāĻŋ āĻāĻ āĻļā§āĻĢā§āϰ āϏāĻŦ āĻ āϰā§āĻĄāĻžāϰ āĻļā§āώ āĻšā§ā§ āϝāĻžā§, āϏ⧠āĻ āύā§āϝ āĻļā§āĻĢā§āϰ āϏāĻšāĻāĻžāϰā§āϰ āĻāĻžāĻ āĻĨā§āĻā§ āĻ āϰā§āĻĄāĻžāϰ âāĻā§āϰāĻŋâ āĻāϰāϤ⧠āĻĒāĻžāϰ⧠(āĻāĻāĻžāĻ work stealing) đ
đ āĻāĻžāĻā§āϰ āϧāĻžāĻĒ
- āĻĒā§āϰāϤāĻŋāĻāĻŋ P āĻāϰ āĻāĻāĻāĻŋ āĻā§āĻ queue āĻĨāĻžāĻā§ āϝā§āĻāĻžāύ⧠goroutine āĻā§āϞ⧠āĻ āĻĒā§āĻā§āώāĻž āĻāϰā§āĨ¤
- āĻā§āύ⧠M (thread) āĻĢāĻžāĻāĻāĻž āĻĨāĻžāĻāϞā§, P āϤāĻžāĻā§ āĻāĻžāĻ āĻĻā§ā§āĨ¤
- GOMAXPROCS āύāĻŋāϰā§āϧāĻžāϰāĻŖ āĻāϰ⧠āĻā§āĻāĻž P (logical core) āĻŦā§āϝāĻŦāĻšāĻžāϰ āĻšāĻŦā§āĨ¤
- āϝāĻĻāĻŋ āĻā§āύ⧠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 Stealing | idle 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 Thread | Goroutine |
|---|---|---|
| Stack Size | ~1MB āĻĨā§āĻā§ 2MB (fixed) | āĻŽāĻžāϤā§āϰ ~2KB āĻĨā§āĻā§ āĻļā§āϰ⧠āĻšā§ āĻāĻŦāĻ āĻĒā§āϰā§ā§āĻāύ āĻ āύā§āϝāĻžā§ā§ āĻŦāĻžā§ā§ āĻŦāĻž āĻāĻŽā§ (dynamic growth) |
| Managed By | OS kernel | Go runtime (user-space) |
| Context Switch | Slow (Kernel-level) | Fast (User-space) |
| Creation Time | Slow (āĻ āύā§āĻ āĻŦā§āĻļāĻŋ) | 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.
đ§ āύāĻŋāĻā§ āĻāĻžāĻŦā§
- Concurrency vs Parallelism āĻāϰ āĻŽā§āϞ āĻĒāĻžāϰā§āĻĨāĻā§āϝ āĻāĻŋ?
- āĻā§āύ Goroutine lightweight?
- M-P-G āĻŽāĻĄā§āϞ āĻāϰ āĻā§āĻŽāĻŋāĻāĻž āĻāĻŋ?
- Stack growth āĻā§āύ important?
- main() āĻļā§āώ āĻšāϞ⧠program āĻā§āύ terminate āĻšā§?
- Preemption āĻā§āĻāĻžāĻŦā§ scheduler āĻā§ āϏāĻšāĻžā§āϤāĻž āĻāϰā§?
đ§ž āϏāĻžāϰāϏāĻāĻā§āώā§āĻĒ
| āϧāĻžāϰāĻŖāĻž | āĻŽā§āϞ āĻĒā§ā§āύā§āĻ |
|---|---|
| Goroutine | user-space lightweight thread |
| Scheduler | āĻ āύā§āĻ goroutine āĻā§ āĻāĻŽ āϏāĻāĻā§āϝāĻ thread āĻ āĻŽā§āϝāĻžāĻĒ āĻāϰ⧠|
| Stack Management | āĻā§āĻ stack â auto grow/shrink |
| Preemption | scheduler āύāĻŋāĻā§ context switch āĻāϰāĻžāϤ⧠āĻĒāĻžāϰ⧠|
| Efficiency | āϞāĻā§āώāĻžāϧāĻŋāĻ goroutine āϏāĻšāĻā§ manage āĻāϰ⧠|
| Exit Rule | main() āĻļā§āώ â āϏāĻŦ goroutine āĻļā§āώ |
đ āϰāĻŋāϏā§āϰā§āϏ
- đ Go by Example â GoroutinesÂ
- đ Go Tour â Concurrency SectionÂ
- đ Go Blog â Concurrency is Not Parallelism (Rob Pike)Â
- đ Inside the Go Scheduler (Morsmachine)Â
- đĨ Rob Pike â âConcurrency Is Not ParallelismâÂ
- đĨ GopherCon â âInside the Go Schedulerâ by Dmitry VyukovÂ
đ§Š 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 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