WaitGroup — انتظار عدّة goroutines
import "sync"
var wg sync.WaitGroup
for i := 1; i <= 3; i++ {
wg.Add(1)
go func(n int) {
defer wg.Done()
fmt.Println("مهمّة", n)
}(i)
}
wg.Wait() // ينتظر انتهاء الكل
سباق البيانات (Race Condition)
عدّة goroutines تعدّل متغيّرًا معًا → نتائج خاطئة:
counter := 0
// عدّة goroutines تنفّذ counter++ → خطأ
شغّل مع go run -race main.go لكشفها.
Mutex — القفل
يضمن أن goroutine واحدة فقط تصل للبيانات في وقت واحد:
import "sync"
var (
mu sync.Mutex
counter int
)
func increment() {
mu.Lock()
counter++
mu.Unlock()
}
RWMutex
قفل يفرّق بين القراءة (متعدّدة) والكتابة (حصرية):
var mu sync.RWMutex
mu.RLock() // قراءة
mu.RUnlock()
mu.Lock() // كتابة
mu.Unlock()
sync.Once
ينفّذ كودًا مرّة واحدة فقط:
var once sync.Once
once.Do(func() { fmt.Println("مرّة واحدة") })
💡 القاعدة: استخدم القنوات للتواصل، و Mutex لحماية حالة مشتركة بسيطة.
🎯 التالي: الحزم والوحدات (Modules).