Channels

Channel adalah mekanisme komunikasi dan sinkronisasi antar goroutine. Channel memungkinkan goroutine untuk saling bertukar data dengan aman.

Contoh Masalah

Bagaimana cara:

  1. Komunikasi antar goroutine
  2. Sinkronisasi proses concurrent
  3. Mengirim dan menerima data dengan aman

Penyelesaian

package main

import (
    "fmt"
    "time"
)

// 1. Basic channel communication
func sender(ch chan<- string) {
    for i := 1; i <= 5; i++ {
        msg := fmt.Sprintf("Message %d", i)
        ch <- msg
        time.Sleep(100 * time.Millisecond)
    }
    close(ch)
}

func receiver(ch <-chan string) {
    for msg := range ch {
        fmt.Printf("Received: %s\n", msg)
    }
}

// 2. Buffered channel example
func bufferDemo(ch chan int) {
    for i := 1; i <= 3; i++ {
        ch <- i
        fmt.Printf("Sent: %d\n", i)
    }
    close(ch)
}

// 3. Select statement with timeout
func fibonacci(c, quit chan int) {
    x, y := 0, 1
    for {
        select {
        case c <- x:
            x, y = y, x+y
        case <-quit:
            fmt.Println("Fibonacci sequence stopped")
            return
        }
    }
}

// 4. Channel direction
func ping(pings chan<- string, msg string) {
    pings <- msg
}

func pong(pings <-chan string, pongs chan<- string) {
    msg := <-pings
    pongs <- msg
}

func main() {
    // Contoh 1: Basic channel usage
    fmt.Println("Basic Channel Example:")
    ch := make(chan string)
    go sender(ch)
    receiver(ch)

    // Contoh 2: Buffered channel
    fmt.Printf("\nBuffered Channel Example:\n")
    buffCh := make(chan int, 3)
    go bufferDemo(buffCh)
    
    // Read from buffered channel
    for i := range buffCh {
        fmt.Printf("Received: %d\n", i)
    }

    // Contoh 3: Select with timeout
    fmt.Printf("\nSelect with Timeout Example:\n")
    c := make(chan int)
    quit := make(chan int)

    go func() {
        for i := 0; i < 5; i++ {
            fmt.Printf("Fibonacci: %d\n", <-c)
        }
        quit <- 0
    }()

    fibonacci(c, quit)

    // Contoh 4: Channel direction
    fmt.Printf("\nChannel Direction Example:\n")
    pings := make(chan string, 1)
    pongs := make(chan string, 1)
    ping(pings, "passed message")
    pong(pings, pongs)
    fmt.Printf("Message: %s\n", <-pongs)

    // Contoh 5: Select with multiple channels
    fmt.Printf("\nSelect with Multiple Channels:\n")
    ch1 := make(chan string)
    ch2 := make(chan string)

    go func() {
        time.Sleep(200 * time.Millisecond)
        ch1 <- "one"
    }()

    go func() {
        time.Sleep(100 * time.Millisecond)
        ch2 <- "two"
    }()

    for i := 0; i < 2; i++ {
        select {
        case msg1 := <-ch1:
            fmt.Printf("Received from ch1: %s\n", msg1)
        case msg2 := <-ch2:
            fmt.Printf("Received from ch2: %s\n", msg2)
        }
    }

    // Contoh 6: Channel with default case
    fmt.Printf("\nSelect with Default Case:\n")
    tick := time.Tick(100 * time.Millisecond)
    boom := time.After(500 * time.Millisecond)

    for {
        select {
        case <-tick:
            fmt.Println("tick.")
        case <-boom:
            fmt.Println("BOOM!")
            return
        default:
            fmt.Println("    .")
            time.Sleep(50 * time.Millisecond)
        }
    }
}

Penjelasan Kode

  1. Basic Channel

    • Unbuffered channel
    • Send dan receive blocking
    • Close channel
  2. Channel Types

    • Buffered channel
    • Send-only/receive-only
    • Select statement
  3. Channel Patterns

    • Pipeline
    • Fan-out/fan-in
    • Timeout

Output

Basic Channel Example:
Received: Message 1
Received: Message 2
Received: Message 3
Received: Message 4
Received: Message 5

Buffered Channel Example:
Sent: 1
Sent: 2
Sent: 3
Received: 1
Received: 2
Received: 3

Select with Timeout Example:
Fibonacci: 0
Fibonacci: 1
Fibonacci: 1
Fibonacci: 2
Fibonacci: 3
Fibonacci sequence stopped

Channel Direction Example:
Message: passed message

Select with Multiple Channels:
Received from ch2: two
Received from ch1: one

Select with Default Case:
    .
    .
tick.
    .
tick.
    .
tick.
    .
tick.
    .
BOOM!

Tips

  • Gunakan buffered channel sesuai kebutuhan
  • Selalu tutup channel dari sender
  • Gunakan select untuk multiple channels
  • Perhatikan deadlock
  • Channel adalah first-class citizen