Channel
Pada sesi ini kita masih membahas tentang concurrency pada Go yaitu channel
Channel adalah tipe data yang dapat membuat Goroutine saling bertukar informasi atau saling berkomunikasi (send and receive). Channel juga membuat Goroutine menjadi Blocking dan Synchronized.
Untuk membuat sebuah Channel, kita dapat menggunakan make
seperti berikut ini:
ch := make(chan int) // Membuat channel dengan tipe integer
atau
var ch chan int // Membuat channel dengan tipe integer
Operator yang digunakan untuk mengirim dan menerima nilai dengan Channel menggunakan <-
:
ch <- v // Send v to channel ch.
v := <-ch // Receive from ch, and
// assign value to v.
Studi Kasus #1
Pada studi kasus pertama kita akan membuat 1 buah fungsi untuk menghitung total numbers dari slice
. Lalu membuat 1 buah fungsi sebagai main
. Dua fungsi tersebut akan kita anggap sebagai Goroutines.
package main
import "fmt"
func sum(s []int, c chan int) {
sum := 0
for _, v := range s {
sum += v
}
c <- sum // send sum to c
}
func main() {
s := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(s[0:3], c)
go sum(s[1:5], c)
x, y := <-c, <-c // receive from c
fmt.Println(x, y, x+y)
}
Pada kode di atas fungsi sum
berperan sebagai goroutine yang mengirim data melalui Channel. Ini ditandai dengan penggunaan operator c <- sum
.
Sementara itu fungsi main
berperan sebagai goroutine yang menerima nilai melalui Channel. Ini ditandai dengan penggunaan operator x, y := <-c, <-c
.

Kita bisa lihat dari output proses yang terjadi adalah:
5 -> berasal dari proses go sum(s[1:5], c)
17 -> berasal dari proses go sum(s[0:3], c)
22 -> berasal dari proses penambahan di dalam fmt.Println()
Ini membuktikan bahwa goroutines berjalan Asynchronous.
Namun proses Channel bersifat Synchronous. Ini bisa dilihat bahwa program akan menunggu proses nilai yang dikirim melalui Channel selesai terlebih dahulu yaitu:
x, y := <-c, <-c // receive from c
baru menjalankan proses di bawahnya:
fmt.Println(x, y, x+y)
Jadi Channel dapat menjadikan proses Goroutine menjadi Synchronous.
Studi Kasus #2
Pada studi kasus ke-2 ini kita akan membuat 2 fungsi secara independen yang berperan sebagai pengirim dan penerima nilai melalui Channel. Kita hanya menjadikan fungsi main
sebagai tempat memanggil goroutine.
package main
import (
"fmt"
)
func main() {
c := make(chan int)
s := []int{2, 2, 2, 2, 2}
go sum(s, c)
go result(c)
var input string
fmt.Scanln(&input)
}
// Fungsi sum berperan sebagai pengirim nilai melalui Channel
func sum(s []int, c chan int) {
total := 0
for _, v := range s {
total += v
}
c <- total
}
// Fungsi result berperan sebagai penerima nilai melalui Channel
func result(c chan int) {
result := <-c
fmt.Println(result)
}
Pada kode di atas kita bisa melihat bahwa pada fungsi main
, kita menggunakan bantuan fmt.Scanln
untuk blocking program karena kemungkinan fungsi yang dijalankan sebagai goroutine selesai lebih lama daripada program di dalam fungsi main
.
Last updated
Was this helpful?