รูปแบบเซมาฟอร์
จำกัดการทำงานพร้อมกันด้วยเซมาฟอร์ที่ใช้แชนเนล
รูปแบบเซมาฟอร์ เป็นบทเรียน Go Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Go Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
เซมาฟอร์คืออะไร
เซมาฟอร์จำกัดจำนวนโกโรทีนที่ทำงานหนึ่งอย่างพร้อมกัน ช่วยป้องกันการใช้ทรัพยากรจนหมด (เช่น การเปิดการเชื่อมต่อฐานข้อมูลมากเกินไปหรือการส่งคำขอ HTTP ออกไปมากเกินไป)
ช่องสัญญาณแบบมีบัฟเฟอร์เป็นเซมาฟอร์
ช่องสัญญาณแบบมีบัฟเฟอร์ที่มีความจุ N จะทำหน้าที่เป็นเซมาฟอร์แบบนับจำนวน การขอสิทธิ์จะส่งค่าไปยังช่องสัญญาณ (และบล็อกเมื่อเต็ม) ส่วนการคืนสิทธิ์จะรับค่าจากช่องสัญญาณ
sem := make(chan struct{}, 10)
func withSem(f func()) {
sem <- struct{}{} // acquire
defer func() { <-sem }() // release
f()
}หนึ่งโกโรทีนต่องานโดยใช้เซมาฟอร์
สร้างโกโรทีนหนึ่งตัวต่องาน แต่จำกัดการทำงานพร้อมกันด้วยเซมาฟอร์:
sem := make(chan struct{}, 5)
for _, job := range jobs {
sem <- struct{}{}
go func(j Job) {
defer func() { <-sem }()
process(j)
}(job)
}ระบายเซมาฟอร์เมื่อสิ้นสุด
หลังจากเริ่มโกโรทีนทั้งหมดแล้ว ให้อ่านค่าจากเซมาฟอร์จนหมด เพื่อให้แน่ใจว่าทั้งหมดทำงานเสร็จก่อนส่งคืน:
// After the loop, acquire all N slots (blocks until all goroutines release)
for i := 0; i < cap(sem); i++ {
sem <- struct{}{}
}golang.org/x/sync/semaphore
สำหรับเซมาฟอร์แบบถ่วงน้ำหนัก (เช่น โกโรทีนที่ใช้ทรัพยากรในน้ำหนักแตกต่างกัน) ให้ใช้ชนิด semaphore.Weighted:
s := semaphore.NewWeighted(100)
// acquire 10 units
if err := s.Acquire(ctx, 10); err != nil { return err }
defer s.Release(10)
// do workการขอสิทธิ์ตามบริบท
เมธอด Acquire ของเซมาฟอร์แบบถ่วงน้ำหนักจะเคารพบริบท และส่งคืนข้อผิดพลาดหากบริบทถูกยกเลิกก่อนที่เซมาฟอร์จะพร้อมใช้งาน
TryAcquire
s.TryAcquire(n) จะขอหน่วยจำนวน n ก็ต่อเมื่อหน่วยเหล่านั้นพร้อมใช้งานทันที หากไม่เช่นนั้นจะส่งคืน false เหมาะสำหรับการตรวจสอบแบบไม่บล็อก
เซมาฟอร์กับกลุ่มผู้ทำงาน
กลุ่มผู้ทำงานมีโกโรทีนถาวรจำนวนคงที่ ส่วนเซมาฟอร์ทำให้คุณสร้างโกโรทีนตามต้องการได้ แต่ยังจำกัดการทำงานพร้อมกัน ใช้เซมาฟอร์เมื่ออัตราการเข้ามาของงานเปลี่ยนแปลงมาก
การจำกัดการทำงานพร้อมกันของ HTTP
ห่อตัวจัดการหรือไคลเอนต์ HTTP ด้วยเซมาฟอร์ เพื่อป้องกันคำขอขาออกที่ทำงานพร้อมกันหรือโกโรทีนของตัวจัดการขาเข้ามีจำนวนมากเกินไป
การจำกัดการเชื่อมต่อฐานข้อมูล
แทนที่จะใช้เซมาฟอร์ ให้กำหนด db.SetMaxOpenConns(n) และ db.SetMaxIdleConns(m) — แพ็กเกจ sql จะจัดการการทำงานพร้อมกันของกลุ่มการเชื่อมต่อภายในให้เอง
ความเป็นธรรมของเซมาฟอร์
เซมาฟอร์ที่ใช้ช่องสัญญาณแบบมีบัฟเฟอร์มีความเป็นธรรมโดยประมาณ (เป็น FIFO สำหรับโกโรทีนที่บล็อกขณะส่ง) แต่ไม่ได้รับประกันอย่างเคร่งครัด แพ็กเกจเซมาฟอร์แบบถ่วงน้ำหนักให้การรับประกันความเป็นธรรมที่เข้มงวดกว่า
ตรวจสอบอย่างรวดเร็ว
ช่องสัญญาณแบบมีบัฟเฟอร์นำมาใช้เป็นเซมาฟอร์ได้อย่างไร
สรุป: รูปแบบเซมาฟอร์
ประเด็นสำคัญ:
- ใช้ช่องสัญญาณแบบมีบัฟเฟอร์ sem := make(chan struct{}, N) สำหรับเซมาฟอร์แบบง่าย
- ส่งค่าเพื่อขอสิทธิ์ รับค่าเพื่อคืนสิทธิ์ และใช้ defer เพื่อคืนสิทธิ์เสมอ
- ใช้ golang.org/x/sync/semaphore สำหรับรูปแบบที่กำหนดน้ำหนักและรองรับบริบท
- ใช้ errgroup.SetLimit เพื่อจำกัดการทำงานพร้อมกันอย่างง่ายต่อกลุ่ม
คำถามที่พบบ่อย
บทเรียน “รูปแบบเซมาฟอร์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “รูปแบบเซมาฟอร์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Go Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “รูปแบบเซมาฟอร์”
จำกัดการทำงานพร้อมกันด้วยเซมาฟอร์ที่ใช้แชนเนล คุณปฏิบัติ Go Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Go Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Go Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “รูปแบบเซมาฟอร์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Go Academy นี้ได้ไหม
ได้ บทเรียน Go Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- รูปแบบไปป์ไลน์และขั้นตอน
- errgroup สำหรับจัดการข้อผิดพลาดพร้อมกัน
- รูปแบบเซมาฟอร์
- การตรวจจับการรั่วไหลและการยกเลิก