36 / 68

Channel

Kanallar orqali ma'lumot almashish

Go dasturlash tilida kanal (channel) — bu turli goroutinelar o'rtasida xavfsiz ma'lumot almashish va ularni sinxronlashtirish vositasidir.

Go falsafasida mashhur qoida bor: "Xotirani ulashish orqali aloqa qilmang, balki aloqa qilish (kanallar) orqali xotirani ulashing".


1. Kanal yaratish (make())

Kanal yaratish uchun o'rnatilgan make() funksiyasidan va chan kalit so'zidan foydalaniladi:

example.go
ch := make(chan int)

Bu yerda chan int ushbu kanal faqat butun son (int) turidagi ma'lumotlarni o'tkazishini bildiradi.

example.go
package main

import "fmt"

func main() {
    number := make(chan int)

    fmt.Printf("Kanal turi: %T\n", number)
    fmt.Printf("Kanal manzili: %v\n", number)
}

Natija:

kod
Kanal turi: chan int
Kanal manzili: 0xc00007a060

2. Kanal amallari: Yuborish va Qabul qilish (<-)

Kanalga ma'lumot yuborish va undan qabul qilib olish uchun strelka <- operatori ishlatiladi:

1. Kanalga ma'lumot yuborish:

example.go
kanalNomi <- ma'lumot

Masalan: number <- 15

2. Kanaldan ma'lumot qabul qilish:

example.go
qabul_qilingan := <-kanalNomi

yoki to'g'ridan-to'g'ri chop etish: fmt.Println(<-kanalNomi)


3. Misol: Goroutine va Kanal hamkorligi

example.go
package main

import "fmt"

func channelData(number chan int, message chan string) {
    // Kanallarga ma'lumot uzatamiz
    number <- 15
    message <- "Go Kanallarini o'rganish"
}

func main() {
    // Kanallarni yaratamiz
    number := make(chan int)
    message := make(chan string)

    // Goroutineni ishga tushiramiz
    go channelData(number, message)

    // Kanallardan ma'lumotni qabul qilib olamiz
    fmt.Println("Raqam:", <-number)
    fmt.Println("Xabar:", <-message)
}

Natija:

kod
Raqam: 15
Xabar: Go Kanallarini o'rganish

4. Kanallarning bloklovchi (Blocking) tabiati

Goda oddiy kanallar sinxron (to'xtatuvchi/bloklovchi) xususiyatga ega:

  1. Yuborishda bloklanish: Goroutine kanalga ma'lumot yuborgan paytda, boshqa biror goroutine ushbu ma'lumotni qabul qilib olmaguncha, yuboruvchi goroutine to'xtab turadi (kutadi).
  2. Qabul qilishda bloklanish: Agar goroutine kanaldan ma'lumot kutayotgan bo'lsa, kanalga ma'lumot kelmaguncha u keyingi qatorga o'tmasdan kutib turadi.

1. Yuborishda bloklanish misoli

example.go
package main

import "fmt"

func sendData(ch chan string) {
    // Ma'lumot qabul qilinmaguncha keyingi qatorga o'tmaydi
    ch <- "Jo'natildi! Qabul qilish muvaffaqiyatli bo'ldi"
    fmt.Println("sendData(): Xabar yetkazildi!")
}

func main() {
    ch := make(chan string)

    go sendData(ch)

    // Kanaldan ma'lumotni qabul qilamiz
    fmt.Println("main():", <-ch)
}

Natija:

kod
main(): Jo'natildi! Qabul qilish muvaffaqiyatli bo'ldi
sendData(): Xabar yetkazildi!

Ushbu bloklanish xususiyati tufayli main() funksiyasi goroutine o'z ishini tugatishini hech qanday time.Sleep()larsiz aniq va ishonchli kutib turadi.

2. Qabul qilishda bloklanish misoli

example.go
package main

import "fmt"

func receiveData(ch chan string) {
    // Kanaldan ma'lumot keladi
    fmt.Println(<-ch)
}

func main() {
    ch := make(chan string)

    go receiveData(ch)

    fmt.Println("Ma'lumot yo'q. Qabul qilish bloklangan.")

    // Kanalga ma'lumot yuboramiz
    ch <- "Ma'lumot qabul qilindi. Qabul qilish muvaffaqiyatli bo'ldi"
}

Natija:

kod
Ma'lumot yo'q. Qabul qilish bloklangan.
Ma'lumot qabul qilindi. Qabul qilish muvaffaqiyatli bo'ldi

Bu yerda main() funksiyasi kanalga ma'lumot yuborishdan oldin receiveData() goroutinesini chaqiradi. Kanal hali ma'lumot olmagani uchun avval "Ma'lumot yo'q..." xabari chiqadi, so'ng kanal ma'lumotni yuborgach, receiveData() uni qabul qilib chop etadi.