Buffered va Unbuffered Channel'lar
Go tilida channel
lar orqali goroutinelar o'rtasida xavfsiz ma’lumot almashinuvi amalga oshiriladi. Channel'lar ikki
asosiy turga bo'linadi: unbuffered va buffered. Ularning farqi — ma’lumot yuborish va qabul qilishdagi
sinxronlashuv mexanizmida.
Unbuffered Channel
Unbuffered channelda sender (ma’lumot yuboruvchi) va receiver (ma’lumot qabul qiluvchi) ayni vaqtda mavjud bo'lishi kerak. Aks holda, ulardan biri bloklanadi (kutadi):
- Sender: ma’lumot yuboradi va receiver tayyor bo'lmaguncha kutadi.
- Receiver: channeldan o'qishga harakat qiladi va sender hali yubormaguncha kutadi.
Bu xatti-harakatlar orqali goroutinelar orasida to'liq sinxronlashuv ta'minlanadi.
Misol:
package main
func main() {
ch := make(chan int)
ch <- 10 // Bu yerda hech kim qabul qilmayapti, shuning uchun deadlock bo'ladi
}
Natija:
Bu xatolik main()
ichida hech qanday qabul qiluvchi yo'qligi sababli yuz beradi. Channel yuborilgan qiymatni
uzatolmaydi va dastur deadlock ga uchraydi.
Boshqa misol:
package main
import "fmt"
func main() {
ch := make(chan int)
go func() {
ch <- 10
}()
val := <-ch
fmt.Println("Qabul qilindi:", val)
}
Natija:
Bu misolimizda endi qabul qiluvchi goroutine mavjudligi sababli hech qanday deadlock sodir bo'lmadi.
Buffered Channel
Buffered channelda yuborilgan qiymatlar buferda (xotirada) vaqtincha saqlanadi. Channel e’lon qilinayotganda unga bufer hajmi belgilanadi:
- Sender: bufer to'lmagan bo'lsa, kutmasdan yozadi.
- Receiver: bufer bo'sh bo'lsa, kutadi.
Misol:
package main
import "fmt"
func main() {
ch := make(chan int, 2)
ch <- 1
ch <- 2
fmt.Println(<-ch) // 1
fmt.Println(<-ch) // 2
}
Bu yerda ch <- 1
va ch <- 2
xatolik bermaydi, chunki bufer hajmi 2 ta qiymatni sig'dira oladi.
Yana bir misol ko'ramiz:
package main
import "fmt"
func main() {
n := 3
buffered := make(chan int, n)
// Channelga qiymatlarni yuborish
for i := 1; i <= 3; i++ {
buffered <- i
}
// channel qiymatlarini qabul qilish
for i := 1; i <= 3; i++ {
fmt.Println(<- buffered)
}
}
Natija:
E'tibor berib qaralsa channelga yuborilgan qiymatlar, qanday tartibda berilgan bo'lsa shu tartibda natija ham olinyapdi. Buning sababi channel FIFO(First In First Out - birinchi kirgan — birinchi chiqadi) tartibida ishlaydi.
Unbuffered channellar katta aniqlikdagi sinxron almashuv uchun foydali, buffered channellar esa yuklama balanslash, log yozish, yoki queue sifatida foydalanishda qo'l keladi.
Unbuffered
channel — bloklovchi, sinxron usulda ishlaydi.Buffered
channel — buferga yozadi, asinxron tarzda ishlaydi.- Har ikkisi ham goroutine'lar orasida xavfsiz va tartibli ma’lumot almashuvini ta’minlaydi.
- Foydalanishdagi maqsadga qarab, to'g'ri turdagi channelni tanlash muhim.