การหมดเวลาและตัวนับช่วงเวลา
ใช้ time.After และ time.Tick ร่วมกับ select
การหมดเวลาและตัวนับช่วงเวลา เป็นบทเรียน Go Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Go Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดการกำหนดเวลาสิ้นสุดจึงสำคัญ
หากไม่มีการกำหนดเวลาสิ้นสุด โกโรทีนที่รอช่องสัญญาณทำงานช้าอาจถูกบล็อกตลอดไป แพ็กเกจ time มีเครื่องมือพื้นฐานสำหรับเพิ่มการควบคุมตามเวลาให้กับการดำเนินการกับช่องสัญญาณ
time.After สำหรับการกำหนดเวลาสิ้นสุดครั้งเดียว
time.After(d) คืนช่องสัญญาณที่รับค่าได้หลังผ่านระยะเวลา d ใช้ใน case ของ select เพื่อยกเลิกการรอ
select {
case res := <-ch:
fmt.Println(res)
case <-time.After(2 * time.Second):
fmt.Println("timed out")
}การกำหนดเวลาซ้ำด้วย time.NewTimer
สำหรับตัวจับเวลาที่นำกลับมาใช้ซ้ำได้ ให้ใช้ time.NewTimer และเรียก Reset หลังการใช้งานแต่ละครั้ง เรียก Stop เพื่อป้องกันโกโรทีนของตัวจับเวลารั่วไหล
timer := time.NewTimer(5 * time.Second)
defer timer.Stop()
select {
case <-timer.C:
fmt.Println("timer fired")
}time.Tick เทียบกับ time.NewTicker
time.Tick สะดวกในการใช้งาน แต่ทำให้ ticker ที่อยู่เบื้องหลังรั่วไหล — ควรใช้ time.NewTicker เพื่อให้เรียก Stop() และคืนทรัพยากรได้
ticker := time.NewTicker(500 * time.Millisecond)
defer ticker.Stop()
for range ticker.C {
fmt.Println("tick")
}Ticker ในลูป
ใช้ ticker ร่วมกับช่องสัญญาณ done เพื่อขับเคลื่อนงานที่ทำเป็นระยะและหยุดได้อย่างเรียบร้อย
ticker := time.NewTicker(time.Second)
done := make(chan struct{})
go func() {
for {
select {
case <-ticker.C:
doWork()
case <-done:
ticker.Stop()
return
}
}
}()การรั่วไหลจาก time.After
time.After สร้างตัวจับเวลาใหม่ทุกครั้งที่เรียกใช้ และตัวจับเวลาจะถูกเก็บคืนโดยตัวเก็บขยะไม่ได้จนกว่าจะทำงาน เมื่อใช้ในลูปที่ทำงานถี่ ควรใช้ time.NewTimer + Reset เพื่อหลีกเลี่ยงตัวจับเวลารั่วไหล
กำหนดเวลาสิ้นสุดเทียบกับเวลาหมด
เวลาหมดเป็นระยะเวลาสัมพัทธ์ ("รอ 5 วินาที") ส่วนกำหนดเวลาสิ้นสุดเป็นเวลาที่แน่นอน ("รอจนถึง 14:00 น.") ใช้ time.Until(deadline) เพื่อแปลงกำหนดเวลาสิ้นสุดเป็นระยะเวลาสำหรับ time.After
deadline := time.Now().Add(5 * time.Second)
select {
case v := <-ch:
use(v)
case <-time.After(time.Until(deadline)):
fmt.Println("deadline exceeded")
}ควรใช้ context.WithTimeout
สำหรับตัวจัดการ HTTP และงานที่มีโครงสร้าง ควรใช้ context.WithTimeout แทนการกำหนดเวลาหมดด้วยช่องสัญญาณโดยตรง เพราะจะส่งต่อการยกเลิกไปตามลำดับการเรียกฟังก์ชันโดยอัตโนมัติ
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()การจำกัดอัตราด้วย Ticker
ticker เป็นตัวจำกัดอัตราที่ง่ายที่สุด: ส่งคำขอหนึ่งรายการต่อหนึ่งจังหวะ หากต้องการรองรับการส่งเป็นชุด ให้เติมค่าลงในช่องสัญญาณแบบมีบัฟเฟอร์ไว้ล่วงหน้า แล้วเติมค่าเพิ่มด้วย ticker
requests := make(chan int, 5)
for i := 0; i < 5; i++ { requests <- i }
close(requests)
limiter := time.NewTicker(200 * time.Millisecond)
for req := range requests {
<-limiter.C
fmt.Println("request", req)
}นาฬิกาแบบโมโนโทนิก
ระยะเวลาของตัวจับเวลาใน Go ใช้นาฬิกาแบบโมโนโทนิก ไม่ใช่นาฬิกาตามเวลาจริง จึงไม่ได้รับผลกระทบจากการปรับนาฬิกาของระบบ time.Since และ time.Until ก็ใช้วิธีนี้เช่นกัน
การหยุด ticker อย่างถูกต้อง
หลังจาก ticker.Stop() ช่องสัญญาณของ ticker จะไม่ถูกปิด — เพียงหยุดรับค่าเท่านั้น หากจำเป็น ให้รับค่าที่ค้างอยู่ในช่องสัญญาณออกก่อนส่งคืน
ตรวจสอบความเข้าใจอย่างรวดเร็ว
เหตุใดจึงควรใช้ time.NewTicker แทน time.Tick
ทบทวน: การกำหนดเวลาสิ้นสุดและ Ticker
ประเด็นสำคัญ:
- ใช้ time.After สำหรับการกำหนดเวลาสิ้นสุดครั้งเดียวใน select
- ใช้ time.NewTicker สำหรับงานที่ทำซ้ำ และเรียก Stop() เสมอ
- หลีกเลี่ยง time.After ในลูป — เพราะทำให้ตัวจับเวลารั่วไหล
- ควรใช้ context.WithTimeout สำหรับงานที่ยกเลิกได้
เรียนรู้ Go ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 51
- บทเรียน
- 203
คำถามที่พบบ่อย
บทเรียน “การหมดเวลาและตัวนับช่วงเวลา” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การหมดเวลาและตัวนับช่วงเวลา” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Go Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การหมดเวลาและตัวนับช่วงเวลา”
ใช้ time.After และ time.Tick ร่วมกับ select คุณปฏิบัติ Go Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Go Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Go Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “การหมดเวลาและตัวนับช่วงเวลา” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Go Academy นี้ได้ไหม
ได้ บทเรียน Go Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- คำสั่ง select
- การหมดเวลาและตัวนับช่วงเวลา
- รูปแบบ Fan-in และ Fan-out
- รูปแบบกลุ่มผู้ทำงาน