รูปแบบกลุ่มผู้ทำงาน
สร้างกลุ่มผู้ทำงานกอรูทีนที่มีขนาดคงที่
รูปแบบกลุ่มผู้ทำงาน เป็นบทเรียน Go Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Go Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
worker pool คืออะไร
worker pool สร้างโกโรทีนจำนวนคงที่ไว้ล่วงหน้าเพื่อประมวลผลงานจากคิวที่ใช้ร่วมกัน วิธีนี้จำกัดจำนวนงานที่ทำพร้อมกัน และป้องกันการใช้ทรัพยากรจนหมดจากการสร้างโกโรทีนไม่จำกัด
การนำไปใช้งานพื้นฐาน
สร้างช่องสัญญาณ jobs และโกโรทีนจำนวน N ตัวที่อ่านจากช่องสัญญาณนี้ทั้งหมด:
func workerPool(n int, jobs <-chan Job, results chan<- Result) {
var wg sync.WaitGroup
for i := 0; i < n; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for job := range jobs {
results <- process(job)
}
}()
}
wg.Wait()
close(results)
}การส่งงาน
ส่งงานทั้งหมดไปยังช่องสัญญาณ จากนั้นปิดช่องสัญญาณ worker จะประมวลผลงานทั้งหมดและออกจากลูปการวนอ่านค่าเมื่อช่องสัญญาณถูกปิด
jobs := make(chan Job, 100)
for _, j := range allJobs {
jobs <- j
}
close(jobs) // signals workers to stop after drainingการรวบรวมผลลัพธ์
อ่านผลลัพธ์ไปพร้อมกับการส่งงาน ใช้โกโรทีนสำหรับ pool เพื่อไม่ให้การรวบรวมผลลัพธ์เกิดการหยุดชะงักกับการส่งงาน
results := make(chan Result, 100)
go workerPool(5, jobs, results)
for r := range results {
collect(r)
}การปรับขนาด pool
สำหรับงานที่ใช้ CPU เป็นหลัก ให้กำหนดขนาด pool เป็น runtime.NumCPU() สำหรับงานที่ใช้การรับส่งข้อมูลเป็นหลัก ตัวคูณที่สูงขึ้น (เช่น 10×) จะใช้ประโยชน์จากช่วงเวลาที่ต้องรอได้มากขึ้น ทำ profiling เพื่อหาจุดที่เหมาะสมที่สุด
n := runtime.NumCPU()
if ioHeavy { n = runtime.NumCPU() * 10 }การเพิ่มการยกเลิกด้วยบริบท
ส่งบริบทไปยัง worker เพื่อให้หยุดทำงานก่อนกำหนดเมื่อมีการยกเลิก:
for {
select {
case job, ok := <-jobs:
if !ok { return }
results <- process(ctx, job)
case <-ctx.Done():
return
}
}ทางเลือกแบบ Semaphore
แทนที่จะใช้ pool ของโกโรทีนจำนวนคงที่ ให้ใช้ช่องสัญญาณแบบมีบัฟเฟอร์เป็น semaphore เพื่อจำกัดจำนวนโกโรทีนที่ทำงานพร้อมกัน โดยยังคงสร้างโกโรทีนหนึ่งตัวต่องานได้
sem := make(chan struct{}, 10)
for _, job := range jobs {
sem <- struct{}{}
go func(j Job) {
defer func() { <-sem }()
process(j)
}(job)
}การจัดการข้อผิดพลาด
ส่งข้อผิดพลาดไปพร้อมกับผลลัพธ์โดยใช้โครงสร้างผลลัพธ์ ยกเลิกบริบทเมื่อพบข้อผิดพลาดแรก หรือรวบรวมข้อผิดพลาดทั้งหมดเพื่อรายงานในตอนท้าย
type Result struct{ Val int; Err error }การปรับขนาด pool แบบไดนามิก
สำหรับ pool ที่ปรับตามสถานการณ์ ให้ใช้ golang.org/x/sync/semaphore ซึ่งอนุญาตให้ขอใช้และคืนทรัพยากรแบบมีน้ำหนักได้ จึงรองรับการจำกัดจำนวนงานที่ทำพร้อมกันแบบไดนามิก
worker pool เทียบกับ errgroup
golang.org/x/sync/errgroup มี API ที่ง่ายกว่าสำหรับการสร้างโกโรทีนจำนวน N ตัวและรวบรวมข้อผิดพลาดแรก ใช้ pool เมื่อจำเป็นต้องมี worker ที่นำกลับมาใช้ซ้ำได้อย่างต่อเนื่อง
การปิดระบบอย่างเรียบร้อย
ปิดช่องสัญญาณ jobs เพื่อส่งสัญญาณให้ worker หยุดทำงาน หลังจาก WaitGroup ทำงานเสร็จแล้ว ให้ปิดผลลัพธ์ การส่งงานที่ค้างอยู่ทั้งหมดต้องเกิดขึ้นก่อน close(jobs)
ตรวจสอบความเข้าใจอย่างรวดเร็ว
worker pool ส่งสัญญาณให้ worker หยุดประมวลผลอย่างไร
ทบทวน: Worker Pool
ประเด็นสำคัญ:
- โกโรทีนจำนวน N ที่กำหนดไว้ตายตัวอ่านจากช่องสัญญาณ jobs เดียว
- ปิดช่องสัญญาณ jobs เพื่อส่งสัญญาณให้ worker ทำงานจนเสร็จ
- WaitGroup ติดตามการทำงานที่เสร็จสิ้น และปิดผลลัพธ์เมื่อเสร็จแล้ว
- งานที่ใช้ CPU เป็นหลัก: ขนาด pool ใกล้เคียง NumCPU ส่วนงานที่ใช้การรับส่งข้อมูลเป็นหลัก: ใช้ขนาดที่ใหญ่กว่า
คำถามที่พบบ่อย
บทเรียน “รูปแบบกลุ่มผู้ทำงาน” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “รูปแบบกลุ่มผู้ทำงาน” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Go Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “รูปแบบกลุ่มผู้ทำงาน”
สร้างกลุ่มผู้ทำงานกอรูทีนที่มีขนาดคงที่ คุณปฏิบัติ Go Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Go Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Go Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “รูปแบบกลุ่มผู้ทำงาน” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Go Academy นี้ได้ไหม
ได้ บทเรียน Go Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- คำสั่ง select
- การหมดเวลาและตัวนับช่วงเวลา
- รูปแบบ Fan-in และ Fan-out
- รูปแบบกลุ่มผู้ทำงาน