Channels
Channel adalah mekanisme komunikasi dan sinkronisasi antar goroutine. Channel memungkinkan goroutine untuk saling bertukar data dengan aman.
Contoh Masalah
Bagaimana cara:
- Komunikasi antar goroutine
- Sinkronisasi proses concurrent
- 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
Basic Channel
- Unbuffered channel
- Send dan receive blocking
- Close channel
Channel Types
- Buffered channel
- Send-only/receive-only
- Select statement
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