[৪.৩] ওয়েটগ্রুপ ( WaitGroup)
Go তে WaitGroup হল একটি ফাংশনালিটি যা অনেকগুলো গো-রুটিন কে কনকারেন্টলি রান করতে সাহায্য করে। আমরা গো-রুটিন এ দেখেছি একটি গো-রুটিন তার রেসপন্স পাঠানোর আগেই অনেক সময় মেইন গো-রুটিন বন্ধ হয়ে যায়, সেই প্রবলেম দূর করার জন্য আমরা time.Sleep() মেথড ব্যবহার করে ছিলাম। সেই কাজটাই আমরা WaitGroup ব্যবহার করে করতে পারি। WaitGroup মেইন গো-রুটিন কে অপেক্ষা করার জন্য ফোর্স করে যতক্ষণ পর্যন্ত অন্য গো-রুটিন এর কাজ শেষ না হয়।
WaitGroup sync প্যাকেজের তিনটি ফাংশন নিয়ে কাজ করে, তাহলো :
১। Add(int) এই ফাংশন দ্বারা নির্দেশ করা হয় মেইন গো-রুটিন কতোগুলো গো-রুটিন এর জন্য অপেক্ষা করবে। Add() ফাংশন সর্বদাই ইন্টিজার প্যারামিটার নিয়ে থাকে।
২। Wait() ফাংশন কোড ব্লক করে রাখে যতক্ষন পর্যন্ত Add() ফাংশনের প্যারামিটার শুন্য না হয়।
৩। Done() ফাংশন একটি গো-রুটিন এর এক্সেকিউশন শেষ হলে Add() ফাংশনের প্যারামিটার এর মান এক করে কমিয়ে দেয়।
একটি উদাহরণ দেখা যাক :
package main
import (
"fmt"
"sync"
"time"
)
func routine(waitgroup *sync.WaitGroup, number int) {
defer waitgroup.Done()
fmt.Printf("Starting routine %d \n", number)
time.Sleep(time.Second)
fmt.Printf("Done with routine %d \n", number)
}
func main() {
fmt.Println("Starting main Goroutine")
var waitgroup sync.WaitGroup
for i := 0; i < 5; i++ {
waitgroup.Add(1)
go routine(&waitgroup, i)
}
waitgroup.Wait()
fmt.Println("Finishing main Goroutine")
}
// Output :
// Starting main Goroutine
// Starting routine 4
// Starting routine 2
// Starting routine 3
// Starting routine 0
// Starting routine 1
// Done with routine 1
// Done with routine 0
// Done with routine 3
// Done with routine 4
// Done with routine 2
// Finishing main Goroutine
এই উদাহরণে, আমরা একটি নতুন WaitGroup ভ্যারিয়েবল waitgroup তৈরি করেছি এবং & অপারেটর ব্যবহার করে routine() ফাংশনে একটি রেফারেন্স পাস করেছি। এটি routine() ফাংশনকে তার কাজ শেষ করার পর Done() মেথডকে কল করে WaitGroup আপডেট করার অনুমতি দেয়।
এখানে আমরা Add(1) এর মাধ্যমে গো-রুটিন এড করেছি, তারপর routine() গো-রুটিন কে কল করেছি যার পয়েন্টার &waitgrop এবং ইন্টিজার i আর্গুমেন্ট হিসেবে পাঠিয়েছি। routine() ফাংশনে defer waitgroup.Done() কল করা হয়েছে যাতে একটি গো-রুটিন শেষ হলে Add() এর মান ডিক্রিমেন্ট করে দেয়। সব গো-রুটিন এর কাজ শেষ না হওয়া পর্যন্ত মেইন গো-রুটিন অপেক্ষা করবে waitgroup.Wait() এর জন্য। সব শেষে মেইন গো-রুটিন এক্সেকিউট হয়ে প্রোগ্রাম বন্ধ হয়ে যাবে।
অ্যানোনিমাস গো-রুটিন এর সাথে Waitgroup
অ্যানোনিমাস গো-রুটিন এর সিনট্যাক্স :
Go func ( parameter list ) {
body..........
} ( argument list )
উদাহরণটি দেখি :
package main
import (
"fmt"
"sync"
"time"
)
func main() {
fmt.Println("Starting main Goroutine")
var waitgroup sync.WaitGroup
waitgroup.Add(5)
for i := 0; i < 5; i++ {
go func(waitgroup *sync.WaitGroup, number int) {
defer waitgroup.Done()
fmt.Printf("Starting routine %d \n", number)
time.Sleep(time.Second)
fmt.Printf("Done with routine %d \n", number)
}(&waitgroup, i)
}
waitgroup.Wait()
fmt.Println("Finishing main Goroutine")
}
// Output :
// Starting main Goroutine
// Starting routine 4
// Starting routine 0
// Starting routine 1
// Starting routine 2
// Starting routine 3
// Done with routine 0
// Done with routine 4
// Done with routine 1
// Done with routine 3
// Done with routine 2
// Finishing main Goroutine