Senin, 15 Desember 2014

Concurrency



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      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 bergantian


func main() {
    var c chan string = make(chan string)
    
    go pinger(c)
    go ponger(c)
    go printer(c)
    
    var input string
    fmt.Scanln(&input)

     Go memilik statemen yang lebih khusus dengan memanggil select. Bagian ini akan berkerja seperti 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