35 / 68

Goroutines

Parallel oqimlar

Go dasturlash tilida goroutine — bu bir vaqtning o'zida bir nechta amallarni mustaqil va parallel bajarish imkonini beruvchi juda yengil vaznli (lightweight) oqimdir (concurrency).

Oddiy dasturlarda funksiyalar ketma-ket (sinxron) bajariladi: bitta funksiya to'liq tugamaguncha ikkinchisi boshlanmaydi. Goroutinelar yordamida esa bir nechta mustaqil funksiyalarni parallel (asinxron) ishga tushirish mumkin.


1. Goroutine yaratish (go kalit so'zi)

Oddiy funksiyani goroutine sifatida ishga tushirish uchun uning chaqiruvi oldiga go kalit so'zini qo'yish yetarli:

example.go
func display() {
    // kod
}

// Goroutine sifatida ishga tushiramiz
go display()

2. Misol: Goroutine va asosiy oqim (main)

example.go
package main

import (
    "fmt"
    "time"
)

func display(message string) {
    fmt.Println(message)
}

func main() {
    // Goroutine sifatida chaqiramiz
    go display("1-jarayon")

    // Oddiy sinxron chaqiruv
    display("2-jarayon")
}

Natija:

kod
2-jarayon

[!NOTE] Nega 1-jarayon chiqmadi? Chunki main() funksiyasining o'zi ham bosh (standart) goroutinedir. go display("1-jarayon") fon rejimiga o'tishi bilan main() o'z ishini tugatib qo'ydi va dastur yopildi. Goroutine ulgurishi uchun main() biroz kutib turishi kerak.

Oddiy dastur va Goroutine ishlatilgan dastur qanday ishlashi


3. Goroutinelarni bir vaqtda (parallel) ishlatish

Keling, time.Sleep() yordamida ikkala jarayonning parallel almashib ishlashini ko'ramiz:

example.go
package main

import (
    "fmt"
    "time"
)

func display(message string) {
    for i := 1; i <= 3; i++ {
        fmt.Println(message, i)
        // Jarayonni 1 soniyaga to'xtatib turamiz
        time.Sleep(time.Millisecond * 500)
    }
}

func main() {
    // 1-jarayonni goroutine sifatida boshlaymiz
    go display("1-jarayon")

    // 2-jarayonni oddiy ishga tushiramiz
    display("2-jarayon")
}

Natija:

kod
2-jarayon 1
1-jarayon 1
2-jarayon 2
1-jarayon 2
2-jarayon 3
1-jarayon 3

Ikkala funksiya ham bir vaqtda parallel ishlayotganini ko'rishimiz mumkin.


4. Bir nechta Goroutinelar (Multiple Goroutines)

Bir vaqtning o'zida istalgancha goroutine ishga tushirish mumkin. Ularning bajarilish tartibini operatsion tizim va Go rejalashtiruvchisi (Go Scheduler) belgilaydi, shuning uchun natijalar ketma-ketligi ixtiyoriy (random) bo'lishi mumkin:

example.go
package main

import (
    "fmt"
    "time"
)

func display(message string) {
    fmt.Println(message)
}

func main() {
    go display("1-jarayon")
    go display("2-jarayon")
    go display("3-jarayon")

    // main() tugab qolmasligi uchun 1 soniya kutamiz
    time.Sleep(time.Second * 1)
}

Ehtimoliy Natija:

kod
3-jarayon
1-jarayon
2-jarayon

5. Goroutinelarning afzalliklari

  1. Juda yengil vaznli: An'anaviy operatsion tizim oqimlari (threads) bir necha megabayt xotira talab qilsa, bitta goroutine bor-yo'g'i bir necha kilobayt (2 KB) xotira bilan ish boshlaydi. Bitta dasturda yuz minglab goroutinelarni qiynalmasdan ishlatish mumkin.
  2. Asinxron fon vazifalari: Foydalanuvchini kuttirmasdan elektron xat yuborish, hisobot tayyorlash kabi amallarni orqa fonda tez bajarish imkonini beradi.
  3. Kanallar orqali xavfsiz muloqot: Goroutinelar o'zaro Channel (kanallar) orqali ma'lumot almashadi, bu esa poyga holati (race conditions) xavfini keskin kamaytiradi.