GoDasturchi
Goroutines: Running Code Concurrently

Goroutines: Running Code Concurrently

Goroutinalar: kodni bir vaqtda ishga tushirish

Shu paytgacha yozgan har bir dasturingiz ketma-ket ishladi: bir qator tugagach, keyingisi boshlandi. Goroutina — Go'ning yengil ip (thread)i, va uni ishga tushirish oson: har qanday funksiya chaqiruvi oldiga go kalit so'zini qo'yasiz.

example.go
go doSomething()
// dastur doSomething() tugashini kutmaydi — darhol keyingi qatorga o'tadi

Muammo shu yerda: agar main funksiyasi goroutinalar tugashini kutmasa, dastur ular ishini tugatishidan oldin chiqib ketishi mumkin. Yechim — sync.WaitGroup: goroutinalar sonini hisoblab boradigan hisoblagich.

example.go
var wg sync.WaitGroup
wg.Add(1)       // "yana bitta goroutina kutilyapti"
go func() {
    defer wg.Done()  // "men tugadim"
    // ish
}()
wg.Wait()       // hisoblagich nolga tushguncha shu yerda kutadi

Muhim nozik nuqta: agar goroutina tsikl o'zgaruvchisini (i, n) to'g'ridan-to'g'ri ushlab qolsa, barcha goroutinalar bir xil, oxirgi qiymatni ko'rishi mumkin edi (eski Go versiyalarida). Xavfsiz andaza — qiymatlarni goroutina funksiyasiga parametr sifatida uzatish, xuddi Pointers & Memory kursida ko'rgan "qiymatni nusxalash orqali izolyatsiya qilish" g'oyasi kabi.

>_ Exercise

SumSquaresConcurrent(nums []int) int funksiyasini yozing. Har bir son uchun alohida goroutina ishga tushiring — u sonning kvadratini oldindan ajratilgan results slice'ining o'z indeksiga yozadi (shuning uchun umumiy holatga yozishda poyga sharoiti bo'lmaydi). sync.WaitGroup yordamida barcha goroutinalar tugashini kuting, so'ngra resultsdagi barcha qiymatlarni yig'ib, yig'indini qaytaring.

Stuck? Reveal a hint to help you.

Hints (0/4)

Key Takeaway

Key Takeaway:

go f() — funksiyani yangi goroutinada ishga tushiradi, lekin uning tugashini kutmaydi. sync.WaitGroup (Add/Done/Wait) — goroutinalar tugashini kutishning standart usuli. Poyga sharoitidan qochish uchun har bir goroutina umumiy xotiraning o'z, boshqalar bilan kesishmaydigan qismiga yozishi kerak — masalan, slice'ning alohida indeksiga.

NEXT UP

WaitGroups: Waiting for Goroutines to Finish

OUTPUT

$ go run main.go
Kodingizni ishga tushiring

Goroutines: Running Code Concurrently

Goroutinalar: kodni bir vaqtda ishga tushirish

Shu paytgacha yozgan har bir dasturingiz ketma-ket ishladi: bir qator tugagach, keyingisi boshlandi. Goroutina — Go'ning yengil ip (thread)i, va uni ishga tushirish oson: har qanday funksiya chaqiruvi oldiga go kalit so'zini qo'yasiz.

example.go
go doSomething()
// dastur doSomething() tugashini kutmaydi — darhol keyingi qatorga o'tadi

Muammo shu yerda: agar main funksiyasi goroutinalar tugashini kutmasa, dastur ular ishini tugatishidan oldin chiqib ketishi mumkin. Yechim — sync.WaitGroup: goroutinalar sonini hisoblab boradigan hisoblagich.

example.go
var wg sync.WaitGroup
wg.Add(1)       // "yana bitta goroutina kutilyapti"
go func() {
    defer wg.Done()  // "men tugadim"
    // ish
}()
wg.Wait()       // hisoblagich nolga tushguncha shu yerda kutadi

Muhim nozik nuqta: agar goroutina tsikl o'zgaruvchisini (i, n) to'g'ridan-to'g'ri ushlab qolsa, barcha goroutinalar bir xil, oxirgi qiymatni ko'rishi mumkin edi (eski Go versiyalarida). Xavfsiz andaza — qiymatlarni goroutina funksiyasiga parametr sifatida uzatish, xuddi Pointers & Memory kursida ko'rgan "qiymatni nusxalash orqali izolyatsiya qilish" g'oyasi kabi.

>_ Exercise

SumSquaresConcurrent(nums []int) int funksiyasini yozing. Har bir son uchun alohida goroutina ishga tushiring — u sonning kvadratini oldindan ajratilgan results slice'ining o'z indeksiga yozadi (shuning uchun umumiy holatga yozishda poyga sharoiti bo'lmaydi). sync.WaitGroup yordamida barcha goroutinalar tugashini kuting, so'ngra resultsdagi barcha qiymatlarni yig'ib, yig'indini qaytaring.

Stuck? Reveal a hint to help you.

Hints (0/4)

Key Takeaway

Key Takeaway:

go f() — funksiyani yangi goroutinada ishga tushiradi, lekin uning tugashini kutmaydi. sync.WaitGroup (Add/Done/Wait) — goroutinalar tugashini kutishning standart usuli. Poyga sharoitidan qochish uchun har bir goroutina umumiy xotiraning o'z, boshqalar bilan kesishmaydigan qismiga yozishi kerak — masalan, slice'ning alohida indeksiga.

NEXT UP

WaitGroups: Waiting for Goroutines to Finish