Concurrency
Program besar sering banyak sub-program yang lebih kecil. Misalnya server web
menangani permintaan yang terbuat dari
web browser dan
halaman web HTML. Setiap permintaan ditangani program kecil.GO memiliki dukungan yang kaya untuk concurrency menggunakan goroutines dan
saluran. Goroutines
merupakn fungsi yang mampu berjalan secara bersamaa dengan fungsi lain. Untuk membuat goroutine cukup menggunakan kata key Go dengan diikuti oleh fungsi invocation:
package main
import "fmt"
func f(n int) {
for i := 0; i < 10; i++ {
fmt.Println(n, ":", i)
}
}
func main() {
go f(0)
var input string
fmt.Scanln(&input)
}
Program ini terdiri dari dua
goroutines. goroutine pertama adalah implisit dan main finction itu sendiri. goroutine kedua dibuat
ketika menyebut Go f (0). Biasanya, bila kita memanggil fungsi program maka akan
mengeksekusi semua pernyataan dalam fungsi dan kemudian kembali ke
baris berikutnya setelah invocation
tersebut. Dengan goroutine
nisa dengan cepat kembali ke baris berikutnya. mengapa panggilan ke fungsi Scanln telah dimasukkan; tanpa
Scanln program akan keluar
sebelum diberi izin untuk mencetak semua nomor.
Memodifikasi Goroutines
dengan menjalankan 10 goroutines yaitu :func main() {
for i := 0; i < 10; i++ {
go f(i)
}
var input string
fmt.Scanln(&input)
}
Mari kita
tambahkan beberapa delay dengan fungsi menggunakan time.sleep dan rand.Intn. f mencetak angka dari 0 sampai 10 dengan durasi antara 0 dan 250 ms dengan
satu persatu. Maka goroutines akan berjalan
secara bersamaan.
package main
import (
"fmt"
"time"
"math/rand"
)
func f(n int) {
for i := 0; i < 10; i++ {
fmt.Println(n, ":", i)
amt := time.Duration(rand.Intn(250))
time.Sleep(time.Millisecond * amt)
}
}
func main() {
for i := 0; i < 10; i++ {
go f(i)
}
var input string
fmt.Scanln(&input)
}
Channels
Channels memeberikan
solusi dengan memberi dua jalan goroutines untuk
berkomunikasi dengan satu sama
lain.berikut adalah contoh program menggunakan Channels:
package main
import (
"fmt"
"time"
)
func pinger(c chan string) {
for i := 0; ; i++ {
c <- "ping"
}
}
func printer(c chan string) {
for {
msg := <- c
fmt.Println(msg)
time.Sleep(time.Second * 1)
}
}
func main() {
var c chan string = make(chan string)
go pinger(c)
go printer(c)
var input string
fmt.Scanln(&input)
}
Program ini akan mencetak
"ping" secara terus menerus
(tekan enter untuk menghentikannya).
channel
type diwakili dengan kata kunci
chan diikuti oleh
type dan memberikan sebuah pengiriman
dalam bentuk string.
1 1 <- (panah kiri)
operator yang digunakan untuk mengirim
dan menerima pesan pada saluran
2 2 c <-
"ping" berarti mengirim "ping".
3 3 msg: =
<- c berarti
menerima pesan dan menyimpannya dalam msg Garis fmt bisa juga ditulis
seperti ini: fmt.Println
(<- c) dalam hal ini kita bisa menghapus baris sebelumnya.
Menggunakan channel dapat mensinkronisasikan dua goroutines yaitu Ketika pinger mencoba
untuk mengirim pesan pada channel maka akan menunggu
sampai printer siap untuk menerima pesan. (ini
dikenal sebagai blocking) Mari kita
tambahkan pengirim lain untuk
program dan melihat apa yang terjadi.
func ponger(c chan string) {
for i := 0; ; i++ {
c <- "pong"
}
}
memodifikasi
main:
Program ini akan mencetak ping dan pong secara bergantianfunc main() {
var c chan string = make(chan string)
go pinger(c)
go ponger(c)
go printer(c)
var input string
fmt.Scanln(&input)
}
switch tetapi
hanya untuk channel :func main() {
c1 := make(chan string)
c2 := make(chan string)
go func() {
for {
c1 <- "from 1"
time.Sleep(time.Second * 2)
}
}()
go func() {
for {
c2 <- "from 2"
time.Sleep(time.Second * 3)
}
}()
go func() {
for {
select {
case msg1 := <- c1:
fmt.Println(msg1)
case msg2 := <- c2:
fmt.Println(msg2)
}
}
}()
var input string
fmt.Scanln(&input)
}
Program ini mencetak "dari 1" setiap 2 detik
dan "dari 2"
setiap 3 detik. Melakuakn
pengambilan dan pengiriman channel dan apabila lebih dari satu channel maka
secara acak akan mengambil satu dan menyimpannya
Tidak ada komentar:
Posting Komentar