0Pricing
Go Academy · درس

خنق Goroutines

تحكّم في التزامن

خنق Goroutines درس مجاني في Go Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Go Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Go Academy 4 دروس في المجموع.

تحديد التزامن

أحيانًا لا تحدّدون عدد العمليات في الثانية، بل تحدّدون عدد goroutines التي تعمل في الوقت نفسه. يضع هذا حدًا للحمل المتزامن على مورد ما بغض النظر عن التوقيت.

  • يحدّ التوازي
  • يحمي تجمعات الاتصالات
  • يمنع الارتفاعات المفاجئة في استهلاك الذاكرة

قناة الإشارة Semaphore

تعمل القناة ذات التخزين المؤقت كـ semaphore عدّاد. يساوي حجمها السعة القصوى للتزامن. يؤدي الاكتساب إلى إرسال رمز، ويؤدي التحرير إلى استقبال رمز.

sem := make(chan struct{}, 3)

الاكتساب والتحرير

قبل بدء العمل، أرسلوا قيمة إلى القناة لاكتساب خانة، إذ يتوقف التنفيذ إذا كانت ممتلئة. وعند الانتهاء، استقبلوا قيمة لتحرير الخانة وإتاحتها لـ goroutine أخرى.

sem <- struct{}{}        // acquire
// do work
<-sem                    // release

لماذا struct{}

يحتل الهيكل الفارغ struct{}{} صفرًا من البايتات. ويجعل استخدامه عنصرًا للقناة من semaphore إشارةً خالصة بلا هدر للذاكرة.

تحديد تزامن حلقة

أطلقوا goroutine لكل مهمة، لكن اربطوا تنفيذ كل منها بـ semaphore. لا تنفّذ أكثر من cap من goroutines العمل الفعلي بالتزامن، بينما تتوقف البقية عند الاكتساب.

for _, task := range tasks {
    sem <- struct{}{}
    go func(t Task) {
        defer func() { <-sem }()
        process(t)
    }(t)
}

الاقتران مع WaitGroup

يحدّد semaphore التزامن، لكنه لا يخبركم بموعد انتهاء كل شيء. ادمجوه مع sync.WaitGroup للانتظار حتى تكتمل جميع المهام.

var wg sync.WaitGroup
wg.Add(1)
go func() {
    defer wg.Done()
    defer func() { <-sem }()
    process(t)
}()

التحرير داخل defer

حرّروا الخانة دائمًا داخل defer حتى تتحرر حتى إذا حدث panic أثناء العمل أو عاد التنفيذ مبكرًا. يؤدي نسيان التحرير إلى تسريب الخانات، وينتهي الأمر إلى حدوث deadlock للمكتسبين الجدد.

تشغيل كامل مع تحديد التزامن

يشغّل هذا البرنامج ثماني مهام مع السماح بمهمتين متزامنتين كحد أقصى، ويطبع وقتي البدء والانتهاء لإظهار الحد عمليًا.

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    sem := make(chan struct{}, 2)
    var wg sync.WaitGroup
    for i := 0; i < 8; i++ {
        wg.Add(1)
        sem <- struct{}{}
        go func(id int) {
            defer wg.Done()
            defer func() { <-sem }()
            fmt.Println("start", id)
            time.Sleep(20 * time.Millisecond)
            fmt.Println("end", id)
        }(i)
    }
    wg.Wait()
    fmt.Println("done")
}

errgroup مع SetLimit

توفّر حزمة golang.org/x/sync/errgroup الدالة SetLimit لتحديد تزامن مجموعة ونقل أول خطأ إليها. وهي بديل أنظف في حالات كثيرة، مع أنها حزمة خارجية.

تحديد التزامن مقابل تجمع العمال

يعيد تجمع العمال استخدام مجموعة ثابتة من goroutines التي تسحب المهام من قائمة انتظار. أما تحديد التزامن باستخدام semaphore فينشئ goroutine لكل مهمة، لكنه يحدّ من المهام النشطة. تكون التجمعات أخف عند وجود عدد هائل من المهام، بينما تكون semaphores أسهل في الإضافة.

اختيار الحد

بالنسبة إلى استدعاءات قاعدة البيانات، اضبطوا الحد عند حجم تجمع الاتصالات أو أقل منه. وبالنسبة إلى HTTP الصادر، طابقوا حد اتصالات المضيف. يؤدي الحد المرتفع جدًا إلى استنفاد الموارد، بينما يهدر الحد المنخفض جدًا السعة.

تحقق سريع

اختبروا معرفتكم بتحديد التزامن.

مراجعة

لقد تعلّمتم تحديد تزامن goroutines:

  • تعمل القناة ذات التخزين المؤقت كـ semaphore عدّاد
  • يتم الاكتساب بالإرسال والتحرير بالاستقبال داخل defer
  • لا تستهلك عناصر struct{} أي بايتات
  • اقترنوا بها مع WaitGroup للانتظار حتى الاكتمال
  • اضبطوا حجم الحد بما يناسب المورد المحمي

الأسئلة الشائعة

هل درس «خنق Goroutines» مجاني؟

نعم — نص درس «خنق Goroutines» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Go Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Go Academy 4 دروس في المجموع.

ماذا ستتعلم في «خنق Goroutines»؟

تحكّم في التزامن تتمرن على Go Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Go Academy؟

لا تُشترط خبرة سابقة. Go Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «خنق Goroutines»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Go Academy هذا؟

نعم. كل درس في Go Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. مفهوم دلو الرموز
  2. golang.org/x/time/rate
  3. خنق Goroutines
  4. التراجع وإعادة المحاولة
← العودة إلى Go Academy