0Pricing
Go Academy · Pelajaran

Menjalankan Goroutine

Kata kunci go, siklus hidup goroutine, dan WaitGroups

Menjalankan Goroutine adalah pelajaran Go Academy gratis di CoddyKit. Ini adalah pelajaran 1 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Go Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Go Academy mencakup 4 pelajaran total.

Apa Itu Goroutine?

goroutine adalah fungsi ringan yang dieksekusi secara konkuren dan dikelola oleh lingkungan eksekusi Go. Goroutine jauh lebih hemat biaya daripada thread OS — Anda dapat menjalankan ribuan goroutine:

  • Mulai dengan kata kunci go
  • Tumpukan awal ~2KB (bertambah secara dinamis)
  • Dijadwalkan oleh lingkungan eksekusi Go, bukan oleh OS
  • Berkomunikasi melalui saluran, bukan memori bersama

Kata Kunci go

Awali pemanggilan fungsi apa pun dengan go untuk meluncurkannya sebagai goroutine:

package main
import ("fmt"; "time")

func greet(name string) {
    fmt.Printf("Hello, %s!\n", name)
}

func main() {
    go greet("Alice")   // runs concurrently
    go greet("Bob")     // runs concurrently
    time.Sleep(100 * time.Millisecond) // wait for goroutines
    fmt.Println("done")
}

Siklus Hidup Goroutine

Goroutine dimulai saat pernyataan go dijalankan dan berakhir saat fungsinya mengembalikan nilai. Jika main berakhir, semua goroutine dihentikan:

package main
import ("fmt"; "time")

func worker(id int) {
    fmt.Printf("Worker %d starting\n", id)
    time.Sleep(time.Duration(id) * 50 * time.Millisecond)
    fmt.Printf("Worker %d done\n", id)
}

func main() {
    for i := 1; i <= 3; i++ {
        go worker(i)
    }
    time.Sleep(300 * time.Millisecond) // naive wait
}

sync.WaitGroup untuk Koordinasi

Gunakan sync.WaitGroup, bukan penundaan, untuk menunggu goroutine selesai:

package main
import ("fmt"; "sync")

func worker(id int, wg *sync.WaitGroup) {
    defer wg.Done()  // signal completion
    fmt.Printf("Worker %d working\n", id)
}

func main() {
    var wg sync.WaitGroup
    for i := 1; i <= 5; i++ {
        wg.Add(1)           // register one goroutine
        go worker(i, &wg)
    }
    wg.Wait()               // block until all Done()
    fmt.Println("all workers finished")
}

Goroutine Anonim

Luncurkan fungsi anonim secara langsung sebagai goroutine — berguna untuk tugas konkuren yang ditulis langsung di tempat:

package main
import ("fmt"; "sync")

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 3; i++ {
        i := i  // capture loop variable
        wg.Add(1)
        go func() {
            defer wg.Done()
            fmt.Printf("goroutine %d\n", i)
        }()
    }
    wg.Wait()
}

Jebakan Penangkapan Variabel Perulangan

Tanpa menangkap variabel perulangan, semua goroutine dapat melihat nilai yang sama (nilai akhir) — bug konkurensi Go yang klasik:

package main
import ("fmt"; "sync")

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 3; i++ {
        wg.Add(1)
        go func(n int) {  // pass i as argument — safe
            defer wg.Done()
            fmt.Println(n)  // prints 0, 1, 2 in some order
        }(i)
    }
    wg.Wait()
}

Goroutine dibanding Thread

Mengapa goroutine lebih dipilih daripada thread OS:

  • Tumpukan awal 2KB dibanding ~1MB untuk thread OS
  • Pembuatan memerlukan mikrodetik dibanding milidetik
  • Lingkungan eksekusi Go memultipleks goroutine ke thread OS sejumlah GOMAXPROCS
  • Perpindahan goroutine bersifat kooperatif — tidak melibatkan inti sistem
  • Go menangani penjadwalan, sehingga Anda dapat berfokus pada logika

GOMAXPROCS

runtime.GOMAXPROCS mengontrol jumlah thread OS yang menjalankan goroutine secara paralel (secara bawaan sama dengan jumlah CPU):

package main
import ("fmt"; "runtime")

func main() {
    // Default: number of available CPU cores
    fmt.Println("CPUs:", runtime.NumCPU())
    fmt.Println("GOMAXPROCS:", runtime.GOMAXPROCS(0)) // 0 = query without changing

    // Set to 1 for debugging race conditions:
    // runtime.GOMAXPROCS(1)

    fmt.Println("Goroutines:", runtime.NumGoroutine())
}

Kebocoran Goroutine

Kebocoran goroutine terjadi ketika sebuah goroutine dimulai tetapi tidak pernah berakhir. Penyebab umum: penerimaan saluran yang terblokir, kunci eksklusif yang terblokir, atau tidak adanya pembatalan:

package main
import ("fmt"; "time"; "runtime")

func leaky() {
    ch := make(chan int)  // nobody sends to ch
    go func() {
        v := <-ch  // blocks forever — goroutine leaked!
        fmt.Println(v)
    }()
}

func main() {
    leaky()
    time.Sleep(10 * time.Millisecond)
    fmt.Println("goroutines:", runtime.NumGoroutine()) // > 1
}

Praktik Terbaik Goroutine

Pedoman goroutine:

  • Selalu ketahui bagaimana sebuah goroutine akan berakhir
  • Gunakan WaitGroup atau saluran untuk menyinkronkan, bukan penundaan
  • Teruskan variabel perulangan sebagai argumen fungsi, bukan melalui fungsi penutup
  • Batalkan goroutine dengan konteks, jangan biarkan goroutine terus berjalan
  • Gunakan detektor kondisi balapan: go run -race main.go

Pemeriksaan Singkat

Apa cara yang benar untuk menghindari bug penangkapan variabel perulangan dalam goroutine?

Ringkasan: Meluncurkan Goroutine

Ringkasan:

  • Luncurkan dengan go fn() — ringan dan hemat biaya
  • Gunakan sync.WaitGroup untuk menunggu: Add(1), defer Done(), Wait()
  • Tangkap variabel perulangan melalui argumen atau deklarasi ulang
  • Selalu ketahui bagaimana setiap goroutine berakhir — cegah kebocoran
  • Gunakan flag -race untuk mendeteksi kondisi balapan data

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Menjalankan Goroutine” gratis?

Ya — teks lengkap “Menjalankan Goroutine” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Go Academy, upgrade ke CoddyKit PRO. Kursus Go Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Menjalankan Goroutine”?

Kata kunci go, siklus hidup goroutine, dan WaitGroups Kamu berlatih Go Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Go Academy?

Tidak diperlukan pengalaman sebelumnya. Go Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 4.

Berapa lama pelajaran “Menjalankan Goroutine” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Go Academy ini?

Ya. Setiap pelajaran Go Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Menjalankan Goroutine
  2. Channel Tanpa Buffer
  3. Channel Berbuffer
  4. Arah Channel dan Pola Pipeline
← Kembali ke Go Academy