Go Academy · บทเรียน

การจำกัดความเร็ว Goroutine

ควบคุมการทำงานพร้อมกัน

บทเรียน 3 จาก 413 ขั้นตอน

การจำกัดความเร็ว Goroutine เป็นบทเรียน Go Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Go Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน

การจำกัดการทำงานพร้อมกัน

บางครั้งคุณไม่ได้จำกัดจำนวนการทำงานต่อวินาที แต่จำกัดจำนวนกอรูทีนที่ทำงาน พร้อมกัน วิธีนี้จำกัดภาระที่เกิดขึ้นพร้อมกันบนทรัพยากรโดยไม่ขึ้นกับจังหวะเวลา

  • จำกัดการทำงานแบบขนาน
  • ปกป้องพูลการเชื่อมต่อ
  • ป้องกันการใช้หน่วยความจำพุ่งสูง

แชนเนลเซมาฟอร์

แชนเนลที่มีบัฟเฟอร์ทำหน้าที่เป็นเซมาฟอร์แบบนับจำนวน ความจุของแชนเนลเท่ากับจำนวนการทำงานพร้อมกันสูงสุด การขอสิทธิ์จะส่งโทเค็นเข้าไป ส่วนการคืนสิทธิ์จะรับโทเค็นออกมา

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

การขอและคืนสิทธิ์

ก่อนเริ่มงาน ให้ส่งค่าเข้าแชนเนลเพื่อขอช่องว่าง หากแชนเนลเต็ม การดำเนินการจะรอค้าง เมื่อทำงานเสร็จ ให้รับค่าออกมาเพื่อคืนช่องว่างและเปิดช่องให้กอรูทีนอื่น

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

เหตุใดจึงใช้ struct{}

โครงสร้างว่าง struct{}{} ใช้หน่วยความจำเป็นศูนย์ไบต์ การใช้โครงสร้างนี้เป็นชนิดข้อมูลของแชนเนลทำให้เซมาฟอร์เป็นเพียงสัญญาณ โดยไม่สิ้นเปลืองหน่วยความจำ

การจำกัดการทำงานในลูป

เปิดใช้กอรูทีนหนึ่งตัวต่องาน แต่ให้แต่ละตัวต้องผ่านเซมาฟอร์ก่อน อย่างมาก cap กอรูทีนเท่านั้นที่ทำงานจริงพร้อมกัน ส่วนที่เหลือจะรอค้างตอนขอสิทธิ์

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

การใช้ร่วมกับ WaitGroup

เซมาฟอร์จำกัดจำนวนการทำงานพร้อมกัน แต่ไม่ได้บอกว่าทุกอย่างเสร็จสิ้นเมื่อใด ให้ใช้ร่วมกับ sync.WaitGroup เพื่อรอให้งานทั้งหมดเสร็จ

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

คืนสิทธิ์ใน defer

คืนสิทธิ์ใน defer เสมอ เพื่อให้ช่องว่างถูกคืนแม้งานจะเกิดแพนิกหรือจบการทำงานก่อนกำหนด หากลืมคืนสิทธิ์ ช่องว่างจะรั่วไหลและทำให้ผู้ขอสิทธิ์รายใหม่ติดตายได้ในที่สุด

การทำงานแบบจำกัดพร้อมกันครบถ้วน

โปรแกรมนี้ทำงานทั้งหมดแปดงาน โดยให้ทำงานพร้อมกันได้อย่างมากสองงาน และพิมพ์จุดเริ่มต้นกับจุดสิ้นสุดเพื่อแสดงให้เห็นการจำกัดนี้

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 สำหรับจำกัดกลุ่มและส่งต่อข้อผิดพลาดแรก วิธีนี้เหมาะเป็นทางเลือกที่เรียบง่ายกว่าในหลายกรณี แต่เป็นแพ็กเกจภายนอก

การจำกัดการทำงานเทียบกับพูลกอรูทีน

พูลกอรูทีนใช้กอรูทีนจำนวนคงที่ซ้ำเดิม โดยดึงงานจากคิวมาทำ การจำกัดด้วยเซมาฟอร์จะสร้างกอรูทีนหนึ่งตัวต่องาน แต่จำกัดจำนวนตัวที่ทำงานอยู่ พูลใช้ทรัพยากรน้อยกว่าสำหรับงานจำนวนมหาศาล ส่วนเซมาฟอร์เพิ่มเข้ากับโค้ดเดิมได้ง่ายกว่า

การเลือกขีดจำกัด

สำหรับการเรียกฐานข้อมูล ให้ตั้งขีดจำกัดไม่เกินขนาดพูลการเชื่อมต่อ สำหรับ HTTP ขาออก ให้สอดคล้องกับขีดจำกัดการเชื่อมต่อของโฮสต์ ค่าสูงเกินไปทำให้ทรัพยากรหมด ส่วนค่าต่ำเกินไปทำให้ใช้ความสามารถไม่เต็มที่

ตรวจสอบอย่างรวดเร็ว

ทดสอบความรู้เกี่ยวกับการจำกัดการทำงานของคุณ

สรุป

คุณได้เรียนรู้การจำกัดการทำงานของกอรูทีน:

  • แชนเนลที่มีบัฟเฟอร์ทำหน้าที่เป็นเซมาฟอร์แบบนับจำนวน
  • ขอสิทธิ์ด้วยการส่ง และคืนสิทธิ์ด้วยการรับใน defer
  • สมาชิกชนิด struct{} ใช้หน่วยความจำเป็นศูนย์ไบต์
  • ใช้ร่วมกับ WaitGroup เพื่อรอให้งานเสร็จ
  • กำหนดขนาดขีดจำกัดให้เหมาะกับทรัพยากรที่ต้องปกป้อง
เริ่มต้นได้ฟรี

เรียนรู้ Go ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
51
บทเรียน
203

คำถามที่พบบ่อย

บทเรียน “การจำกัดความเร็ว Goroutine” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การจำกัดความเร็ว Goroutine” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Go Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การจำกัดความเร็ว Goroutine”

ควบคุมการทำงานพร้อมกัน คุณปฏิบัติ Go Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Go Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Go Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “การจำกัดความเร็ว Goroutine” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Go Academy นี้ได้ไหม

ได้ บทเรียน Go Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. แนวคิดบักเก็ตโทเค็น
  2. golang.org/x/time/rate
  3. การจำกัดความเร็ว Goroutine
  4. การหน่วงเวลาและลองใหม่
← กลับไปที่ Go Academy