ماڈیول اسباق (1/5)
Goroutines: ہلکا پھلکا متوازی
A گوروٹین کنکرنٹ ایگزیکیوشن کی اکائی ہے جس کا انتظام Go کے ذریعے کیا جاتا ہے۔
رن ٹائم آپ ایک فنکشن کے سامنے go کلیدی لفظ کے ساتھ لانچ کرتے ہیں۔
کال:
go greet("Anna") // chiamata a funzione esistente
go func() { // funzione anonima
fmt.Println("hi")
}()go بیان فوری طور پر واپس آجاتا ہے: گوروٹین اس وقت شروع ہوتا ہے
متوازی اور کال کرنے والا چلتا رہتا ہے۔
وہ "ہلکے وزن" کیوں ہیں
- ابتدائی اسٹیک ~2KB (متحرک طور پر بڑھتا ہے، اگر ضرورت ہو تو سینکڑوں MB تک)۔
- ملٹی پلیکس رن ٹائم (
GOMAXPROCS) کے ذریعہ OS تھریڈز کی ایک چھوٹی سی تعداد پر۔ - ہزاروں/لاکھوں گوروٹینز معمول کے مطابق ہیں۔ OS تھریڈز کے ساتھ وہ ناممکن ہو جائیں گے۔
تصوراتی طور پر یہ "سمورتی آگ اور بھول" ہے، لیکن سب کے ساتھ
ہم آہنگی کے لیے محاوراتی ٹولز (چینلز، sync.WaitGroup,
context)۔
مین انتظار نہیں کرتا
func main() {
go func() { fmt.Println("ciao dalla goroutine") }()
// main esce subito: niente garanzia che la goroutine completi
}جب main واپس آتا ہے، تو عمل ختم ہوجاتا ہے: گوروٹینز حاصل نہیں ہوتے ہیں
"اپنا کام ختم کرنے" کے لیے، وہ صرف ایک ساتھ مارے جاتے ہیں۔
عمل واضح مطابقت پذیری کی ضرورت ہے۔
ہم وقت سازی: ایک پیش نظارہ
تین ٹولز جو آپ اگلے اسباق میں دیکھیں گے:
// 1) Channel: la goroutine "segnala" via canale
done := make(chan struct{})
go func() {
work()
done <- struct{}{}
}()
<-done // attendi
// 2) sync.WaitGroup: N goroutine
var wg sync.WaitGroup
wg.Add(1)
go func() { defer wg.Done(); work() }()
wg.Wait()
// 3) context: cancellazione/timeout propagati"کلاسک" کلوزر ان لوپ بگ
Go 1.21 تک یہ بار بار جانا تھا:
for i := 0; i < 3; i++ {
go func() { fmt.Println(i) }() // stampa "3 3 3" su versioni vecchie
}Go 1.22 سے for متغیر ہر ایک پر تازہ بنایا گیا ہے
iteration، لہذا بگ ڈیفالٹ کی طرف سے طے کیا جاتا ہے. پرانے کوڈ بیس میں آپ کریں گے۔
اب بھی فکس پیٹرن دیکھیں:
for i := 0; i < 3; i++ {
i := i // shadow esplicito
go func() { fmt.Println(i) }()
}
// oppure passa come argomento:
for i := 0; i < 3; i++ {
go func(n int) { fmt.Println(n) }(i)
}گوروٹین != OS تھریڈ
| پہلو | گوروٹین | OS تھریڈ |
|---|---|---|
| ابتدائی اسٹیک | ~2 KB | 1–8 MB (شروع میں مختص) |
| تخلیق | نینو سیکنڈز | مائیکرو سیکنڈز |
| شیڈولنگ | رن ٹائم جاؤ (کوآپریٹو) | دانا (قبل از وقت) |
| عملی شمار | 100K+ | چند ہزار |
ایک واحد OS تھریڈ بہت سے گوروٹینز کی میزبانی کر سکتا ہے۔ رن ٹائم حرکت کرتا ہے۔ ضرورت پڑنے پر دھاگوں کے پار goroutines۔
اسے آزمائیں
گریٹ فنکشن کو گوروٹین کے طور پر شروع کریں اور وقت کے ساتھ 100ms انتظار کریں۔ مین سے باہر نکلنے سے پہلے سو جائیں۔
اشارہ دکھائیں۔
ایک فنکشن کال کے سامنے `go` گوروٹین کا آغاز کرتا ہے۔
3 کوششوں کے بعد حل دستیاب ہے۔
گوروٹین کے بطور ایک گمنام فنکشن شروع کریں جو 'ہائے' پرنٹ کرتا ہے۔
اشارہ دکھائیں۔
ایک گمنام فنکشن کو ٹریلنگ `()` کے ساتھ کہا جاتا ہے: `go func(){...}()`۔
3 کوششوں کے بعد حل دستیاب ہے۔
اگر گوروٹین مکمل ہونے سے پہلے `مین` باہر نکل جائے تو کیا ہوگا؟
func main() {
go work()
// main ritorna immediatamente
}Recap
go f()f() کو بیک وقت لانچ کرتا ہے۔ یہ فوری طور پر واپس آتا ہے.- گوروٹین = ~2 KB ابتدائی، چند OS تھریڈز پر ملٹی پلیکس۔
mainانتظار نہیں کرتا: آپ کو ہم آہنگی کی ضرورت ہے (چینل/ویٹ گروپ/ سیاق و سباق)۔time.Sleepصرف تدریسی ہے، پیداوار میں مطابقت پذیری کے لیے کبھی نہیں۔- Go 1.22 سے
forمتغیر ہر تکرار پر "تازہ" ہے (مزید "3 3 3" بگ نہیں)۔