Select و WaitGroup

select برای چندگانه‌سازی Channel، WaitGroup برای صبر و Mutex برای قفل.

select — منتظر چند Channel

select مثل switch اما برای Channel ها — منتظر می‌ماند تا یکی آماده شود:

select {
case msg := <-ch1:
    fmt.Println("از کانال ۱:", msg)
case msg := <-ch2:
    fmt.Println("از کانال ۲:", msg)
}

مثال: مسابقه دو کانال

ch1 := make(chan string)
ch2 := make(chan string)

go func() { time.Sleep(time.Second); ch1 <- "اولی" }()
go func() { time.Sleep(2 * time.Second); ch2 <- "دومی" }()

for i := 0; i < 2; i++ {
    select {
    case msg1 := <-ch1:
        fmt.Println("دریافت:", msg1)
    case msg2 := <-ch2:
        fmt.Println("دریافت:", msg2)
    }
}

select با timeout

select {
case msg := <-ch:
    fmt.Println("دریافت شد:", msg)
case <-time.After(2 * time.Second):
    fmt.Println("مهلت تمام شد!")   ← timeout
}

select با default (غیربلاک)

select {
case msg := <-ch:
    fmt.Println(msg)
default:
    fmt.Println("داده‌ای موجود نیست")   ← بدون صبر
}

sync.WaitGroup — صبر برای گروهی از کارها

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()   ← صبر تا صفر شود
fmt.Println("همه کارها تمام شد")

sync.Mutex — قفل متقابل

وقتی چند Goroutine به متغیر مشترک دسترسی دارند:

var (
    counter int
    mu      sync.Mutex
)

func increment() {
    mu.Lock()         ← قفل
    counter++
    mu.Unlock()       ← باز کردن
}
بدون Mutex، شرط مسابقه (Race Condition) رخ می‌دهد — نتیجه‌ها نادرست و غیرقابل پیش‌بینی می‌شوند!

مثال کامل: شمارنده امن

func main() {
    var (
        counter int
        mu      sync.Mutex
        wg      sync.WaitGroup
    )

    for i := 0; i < 100; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            mu.Lock()
            counter++
            mu.Unlock()
        }()
    }

    wg.Wait()
    fmt.Println(counter)   ← همیشه 100 ✓
}

جمع‌بندی ابزارهای همزمانی

ابزارکاربرد
goاجرای همزمان
channelارتباط و انتقال داده
selectچندگانه‌سازی کانال‌ها
sync.WaitGroupصبر برای اتمام گروه
sync.Mutexقفل متغیر مشترک

این مبحث بخشی از دوره آموزش کامل گو است.

ابزارهای مرتبط