การตรวจจับการรั่วไหลและการยกเลิก
ตรวจสอบให้กอรูทีนออกจากการทำงานและป้องกันการรั่วไหล
การตรวจจับการรั่วไหลและการยกเลิก เป็นบทเรียน Go Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Go Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
การรั่วไหลของโกโรทีนคืออะไร
การรั่วไหลของโกโรทีนเกิดขึ้นเมื่อโกโรทีนเริ่มทำงานแต่ไม่สิ้นสุด โกโรทีนที่รั่วไหลจะสะสมเพิ่มขึ้นเรื่อย ๆ ใช้หน่วยความจำสแตกและ CPU จนกว่าโพรเซสจะถูกยุติ
การรั่วไหลที่พบบ่อย: การรับค่าจากช่องสัญญาณที่ถูกบล็อก
โกโรทีนที่รอรับค่าจากช่องสัญญาณซึ่งไม่มีวันได้รับค่าจะถูกบล็อกตลอดไป:
go func() {
v := <-ch // leaks if no sender and ch is never closed
use(v)
}()การรั่วไหลที่พบบ่อย: ไม่มีสัญญาณเสร็จสิ้น
โกโรทีนในลูป for ที่ไม่มีเงื่อนไขออกหรือช่องสัญญาณเสร็จสิ้นจะทำงานตลอดไป:
go func() {
for {
work()
// no exit condition — leaks
}
}()ตรวจจับการรั่วไหลด้วย goleak
go.uber.org/goleak ตรวจสอบว่าไม่มีโกโรทีนรั่วไหลเมื่อการทดสอบสิ้นสุดลง:
func TestMyFunc(t *testing.T) {
defer goleak.VerifyNone(t)
myFunc() // should not leak goroutines
}ใช้บริบทเป็นวิธีแก้ไข
วิธีมาตรฐานในการหยุดโกโรทีนที่ทำงานเป็นเวลานานคือใช้บริบท ส่ง ctx ให้โกโรทีน แล้วใช้ select ตรวจสอบ ctx.Done()
go func(ctx context.Context) {
for {
select {
case work := <-workCh:
process(work)
case <-ctx.Done():
return // clean exit
}
}
}(ctx)รูปแบบช่องสัญญาณเสร็จสิ้น
สำหรับกรณีที่ง่ายกว่าและไม่ใช้บริบท ให้ใช้ช่องสัญญาณเสร็จสิ้นโดยเฉพาะ ปิดช่องสัญญาณนี้เพื่อกระจายสัญญาณหยุดไปยังโกโรทีนทั้งหมดที่กำลังอ่านจากช่องสัญญาณ
done := make(chan struct{})
go func() {
select {
case v := <-data: use(v)
case <-done: return
}
}()
close(done) // stops goroutineตรวจจับด้วยรันไทม์
พิมพ์จำนวนโกโรทีนเพื่อตรวจจับการเพิ่มขึ้นระหว่างการทำงานของโปรแกรม:
fmt.Println("goroutines:", runtime.NumGoroutine())โกโรทีนของเซิร์ฟเวอร์ HTTP
net/http จัดการโกโรทีนแยกตามคำขอให้โดยอัตโนมัติ และทำความสะอาดโกโรทีนเมื่อคำขอเสร็จสิ้น แต่ตัวจัดการคำขอที่เปิดโกโรทีนโดยไม่ทำความสะอาดก็ยังทำให้เกิดการรั่วไหลได้
การทดสอบการรั่วไหล
เรียกใช้ชุดการทดสอบโดยใช้ goleak เป็น TestMain หรือใช้ defer ในแต่ละการทดสอบ โกโรทีนใดก็ตามที่ยังไม่สิ้นสุดหลังเนื้อหาการทดสอบทำงานเสร็จ จะทำให้การทดสอบล้มเหลว
func TestMain(m *testing.M) {
goleak.VerifyTestMain(m)
}การรั่วไหลจาก Time.After
time.After ใน select ภายในลูปจะสร้างตัวจับเวลาใหม่ในการวนซ้ำแต่ละครั้ง ซึ่งไม่สามารถถูกเก็บคืนโดยตัวเก็บขยะได้จนกว่าตัวจับเวลาจะทำงานเสร็จ ให้แทนที่ด้วย time.NewTimer และ Reset
การรั่วไหลจากโกโรทีนที่ส่งคืนข้อผิดพลาด
หากโกโรทีนควรส่งผลลัพธ์ผ่านช่องสัญญาณ แต่หยุดทำงานก่อนกำหนดเนื่องจากข้อผิดพลาดโดยไม่ส่งค่า โกโรทีนผู้รับจะถูกบล็อกตลอดไป ให้ส่งค่าหรือปิดช่องสัญญาณในทุกเส้นทางการทำงานเสมอ
ตรวจสอบอย่างรวดเร็ว
วิธีมาตรฐานที่สุดในการหยุดโกโรทีนที่ทำงานเป็นเวลานานใน Go คืออะไร
สรุป: การตรวจจับการรั่วไหลและการยกเลิก
ประเด็นสำคัญ:
- การรั่วไหลของโกโรทีนจะสะสมเพิ่มขึ้น ให้ตรวจสอบด้วย runtime.NumGoroutine()
- goleak ในการทดสอบจะตรวจจับการรั่วไหลของโกโรทีนโดยอัตโนมัติ
- ให้โกโรทีนมีเส้นทางออกเสมอ ได้แก่ บริบท ช่องสัญญาณเสร็จสิ้น หรืออินพุตที่ถูกปิด
- time.After ในลูปทำให้ตัวจับเวลารั่วไหล ให้ใช้ NewTimer+Reset
คำถามที่พบบ่อย
บทเรียน “การตรวจจับการรั่วไหลและการยกเลิก” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การตรวจจับการรั่วไหลและการยกเลิก” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- รูปแบบไปป์ไลน์และขั้นตอน
- errgroup สำหรับจัดการข้อผิดพลาดพร้อมกัน
- รูปแบบเซมาฟอร์
- การตรวจจับการรั่วไหลและการยกเลิก