Bu örnekte, birden fazla goroutine kullanarak aynı anda birden fazla imaj dosyasını işleyeceğiz. İşlemimiz yükleme, kırpma ve sırayla kaydetmeyi içerir. Kanalları kullanarak bir sonraki adıma başlayacağımızı belirtiyoruz. İmajları işleme için tüm adımlar tamamlandığında, ilgili tüm kanallarını kapatıyoruz. Tüm imajlar işlendikten sonra uygulama kapanıyor. Bu eşzamanlı bir işlem olduğundan, önce hangi imajın işleneceğini asla garanti edemezsiniz. Bu arada aslında imajları yüklemeyeceğiz, kırpmayacak ve kaydetmeyeceğiz!


Örnek


main.go


package main

import (
"fmt"
"math/rand"
"sync"
"time"

"internal/image"
)

var (
wg sync.WaitGroup
files = []string{"image1.jpg", "image2.jpg", "image3.jpg", "image4.jpg"}
)

func main() {
rand.Seed(time.Now().UnixNano())

fmt.Println("START")

wg.Add(len(files))

for _, file := range files {
// Start uploading asynchronously.
go image.New(&wg, file).Upload()
}

wg.Wait()

fmt.Println("FINISH")
}

upload.go


Bazı işlem sürelerini simüle etmek için rastgele uyuyoruz.


package image

import (
"fmt"
"math/rand"
"sync"
"time"
)

type Image struct {
wg *sync.WaitGroup
name string
}

func New(wg *sync.WaitGroup, name string) Image {
return Image{
wg: wg,
name: name,
}
}

func (i Image) Upload() {
defer i.wg.Done()

fmt.Println("upload(str) -", i.name)

wait := rand.Intn(len([]int{0, 1, 2, 3, 4, 5, 6}))
time.Sleep(time.Duration(wait) * time.Second)

fmt.Println("upload(end) -", i.name, wait, "sec")

cropDone := make(chan bool)
saveDone := make(chan bool)

// Start cropping asynchronously.
go i.crop(cropDone, saveDone)

// Upload ending depends on completion of crop and save operations so blocking here.
<- cropDone
<- saveDone
}

func (i Image) crop(cropDone, saveDone chan <- bool) {
fmt.Println("crop(str) -", i.name)

wait := rand.Intn(len([]int{0, 1, 2, 3, 4, 5, 6}))
time.Sleep(time.Duration(wait) * time.Second)

fmt.Println("crop(end) -", i.name, wait, "sec")

// Instruct channel that crop is done.
cropDone <- true // close(cropDone)

// Start saving asynchronously.
go i.save(saveDone)
}

func (i Image) save(saveDone chan <- bool) {
fmt.Println("save(str) -", i.name)

wait := rand.Intn(len([]int{0, 1, 2, 3, 4, 5, 6}))
time.Sleep(time.Duration(wait) * time.Second)

fmt.Println("save(end) -", i.name, wait, "sec")

// Instruct channel that save is done.
saveDone <- true // close(saveDone)
}

Test


Aşağıda görebileceğiniz gibi, kazanan image3!


START
upload(str) - image1.jpg
upload(str) - image2.jpg
upload(str) - image3.jpg
upload(str) - image4.jpg
upload(end) - image1.jpg 2 sec
crop(str) - image1.jpg
crop(end) - image1.jpg 0 sec
save(str) - image1.jpg
upload(end) - image4.jpg 3 sec
upload(end) - image3.jpg 3 sec
crop(str) - image3.jpg
crop(str) - image4.jpg
upload(end) - image2.jpg 5 sec
crop(str) - image2.jpg
crop(end) - image2.jpg 2 sec
crop(end) - image3.jpg 4 sec
save(str) - image2.jpg
save(str) - image3.jpg
save(end) - image3.jpg 0 sec
save(end) - image1.jpg 6 sec
crop(end) - image4.jpg 5 sec
save(str) - image4.jpg
save(end) - image2.jpg 3 sec
save(end) - image4.jpg 6 sec
FINISH

Total time
image3 - 7 sec
image1 - 8 sec
image2 - 10 sec
image4 - 14 sec