0Pricing
Go Academy · บทเรียน

การตรวจจับการรั่วไหลและการยกเลิก

ตรวจสอบให้กอรูทีนออกจากการทำงานและป้องกันการรั่วไหล

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

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

  1. รูปแบบไปป์ไลน์และขั้นตอน
  2. errgroup สำหรับจัดการข้อผิดพลาดพร้อมกัน
  3. รูปแบบเซมาฟอร์
  4. การตรวจจับการรั่วไหลและการยกเลิก
← กลับไปที่ Go Academy