Lompat ke konten Lompat ke sidebar Lompat ke footer

Golang Concurrency #19

 

Penjelasan Model M:N Scheduling di Goroutine

Goroutine di Go lebih ringan dibandingkan thread OS karena menggunakan M:N scheduling.
Mari kita bahas dari dasar dan pelan-pelan!


1. Apa Itu Thread OS?

Biasanya, bahasa pemrograman menggunakan Thread OS (Operating System Thread) untuk menjalankan tugas secara concurrent (bersamaan).

Misalnya di C, Java, atau Python, jika kita membuat 1000 thread, maka sistem operasi harus membuat 1000 thread OS yang dikendalikan langsung oleh CPU.

🔴 Masalahnya:

  • Thread OS berat karena setiap thread memerlukan memori stack yang besar (biasanya 1MB per thread).
  • Switching antar thread (context switch) butuh waktu lama karena OS harus menyimpan dan memulihkan state setiap thread saat berpindah.

2. Apa Itu Goroutine?

Goroutine adalah "user-space thread" yang dikelola oleh Go runtime, bukan langsung oleh OS.

✔️ Keunggulan Goroutine:

  • Lebih ringan (hanya butuh sekitar 2 KB memori stack saat dibuat).
  • Bisa membuat jutaan goroutine tanpa membebani sistem.
  • Go runtime yang menangani scheduling (penjadwalan) goroutine, bukan OS.

3. Bagaimana Model M:N Scheduling di Go Bekerja?

Go menggunakan M:N scheduling, yang berarti:

M Goroutine berjalan di N Thread OS

Daripada menjalankan setiap goroutine dalam thread OS, Go memiliki sistem yang lebih efisien:

  • Goroutine (M unit kerja) → Tidak langsung ke thread OS, tetapi dijalankan oleh scheduler Go.
  • Scheduler Go → Memetakan goroutine ke thread OS yang tersedia.
  • Thread OS (N thread) → Menjalankan banyak goroutine dalam satu thread secara bergantian.

Contoh sederhana:
Jika kita memiliki 1000 goroutine, Go tidak akan membuat 1000 thread OS.
Misalnya, Go hanya menggunakan 4 thread OS, lalu menjalankan goroutine dalam thread-thread ini dengan cara bergantian.


4. Bagaimana Go Scheduler Mengatur Goroutine?

Go scheduler memiliki beberapa komponen penting:

  1. G (Goroutine) – Representasi dari satu unit kerja (fungsi yang berjalan sebagai goroutine).
  2. M (Thread OS - Machine) – Thread OS tempat goroutine berjalan.
  3. P (Processor) – Unit virtual yang mengelola daftar goroutine dan memberikan tugas ke thread OS.

🔹 Langkah Kerja Go Scheduler:

  1. Goroutine dibuat dan masuk ke dalam antrean di Processor (P).
  2. Thread OS (M) mengambil tugas dari Processor dan menjalankan goroutine.
  3. Jika satu goroutine harus menunggu (misalnya karena I/O), Go runtime bisa memindahkan goroutine lain ke thread OS yang sama agar tetap efisien.
  4. Jika ada lebih banyak goroutine daripada kapasitas thread OS yang tersedia, Go runtime akan melakukan preemptive scheduling (menghentikan sementara goroutine yang sedang berjalan dan menggantinya dengan yang lain).

5. Perbandingan Model 1:1, N:1, dan M:N

ModelPenjelasanContoh BahasaKelebihanKekurangan
1:1 (Setiap thread program = 1 thread OS)Setiap unit kerja diwakili oleh thread OS langsungJava, Python, C++Bisa memanfaatkan multi-coreBerat, karena banyak context switching
N:1 (Semua thread aplikasi dijalankan dalam 1 thread OS)Semua tugas dijalankan dalam satu thread OSGreen Threads (Ruby)Ringan, tidak perlu context switching OSTidak bisa menggunakan multi-core CPU
M:N (Banyak goroutine ke lebih sedikit thread OS)Banyak goroutine bisa berjalan pada lebih sedikit thread OSGoroutine (Go), ErlangEfisien, ringan, dan bisa menggunakan multi-coreKompleks, butuh scheduler runtime

6. Contoh Ilustrasi M:N Scheduling

Bayangkan kita memiliki 3 worker dan 10 tugas:

Goroutine (M)SchedulerThread OS (N)
G1, G2, G3 →P1 →M1
G4, G5, G6 →P2 →M2
G7, G8, G9, G10 →P3 →M3
  1. G1, G2, G3 berjalan di Thread OS M1.
  2. Jika G1 menunggu I/O, maka G2 langsung dieksekusi tanpa perlu membuat thread baru.
  3. Jika semua Processor sibuk, Go runtime bisa membuat tambahan thread OS secara otomatis.

7. Kesimpulan: Kenapa M:N Scheduling di Go Sangat Efisien?

Lebih ringan dibandingkan thread OS (butuh 2 KB vs 1MB per thread OS).
Tidak terlalu sering melakukan context switching yang berat.
Memanfaatkan multi-core CPU dengan optimal.
Goroutine bisa berpindah ke thread OS lain tanpa overhead besar.
Scheduler Go bisa menyesuaikan jumlah thread OS yang aktif agar optimal.

Karena itu, goroutine jauh lebih efisien dibandingkan thread OS langsung, dan inilah yang membuat Go sangat cocok untuk aplikasi high-concurrency seperti server web, microservices, dan sistem real-time.


Semoga ini membantu! Jika masih kurang jelas, bisa ditanyakan lebih lanjut. 🚀