เราจะพยายามรับการล็อคแบบ mutex ได้อย่างไรไม่ว่าจะยกเลิกทันที (เหมือนที่ TryLock ทำในการใช้งานอื่น ๆ ) หรือโดยการสังเกตกำหนดเวลาบางรูปแบบ (โดยพื้นฐานแล้ว LockBefore )?
ตอนนี้ฉันนึกถึง 2 สถานการณ์ที่สิ่งนี้จะเป็นประโยชน์อย่างมาก และที่ฉันกำลังมองหาวิธีแก้ไข ประการแรกคือ: บริการที่เน้น CPU มากซึ่งรับคำขอที่มีความละเอียดอ่อนด้านเวลาแฝง (เช่น บริการบนเว็บ) ในกรณีนี้ คุณต้องการดำเนินการบางอย่างเหมือนกับตัวอย่าง RPCService ด้านล่าง เป็นไปได้ที่จะนำไปใช้เป็นคิวผู้ปฏิบัติงาน (พร้อมแชนเนลและสิ่งของ) แต่ในกรณีนี้ จะยากขึ้นในการวัดและใช้ CPU ที่มีอยู่ทั้งหมด นอกจากนี้ยังเป็นไปได้ที่จะยอมรับว่าเมื่อถึงเวลาที่คุณได้รับล็อค รหัสของคุณอาจเกินกำหนดเวลาแล้ว แต่นั่นไม่เหมาะเนื่องจากเป็นการสิ้นเปลืองทรัพยากรจำนวนหนึ่ง และหมายความว่าเราไม่สามารถทำสิ่งต่าง ๆ เช่น "เฉพาะกิจที่เสื่อมโทรมลง" การตอบสนอง".
/* Example 1: LockBefore() for latency sensitive code. */
func (s *RPCService) DoTheThing(ctx context.Context, ...) ... {
if s.someObj[req.Parameter].mtx.LockBefore(ctx.Deadline()) {
defer s.someObj[req.Parameter].mtx.Unlock()
... expensive computation based on internal state ...
} else {
return s.cheapCachedResponse[req.Parameter]
}
}
อีกกรณีหนึ่งคือเมื่อคุณมีวัตถุจำนวนมากที่ควรสัมผัส แต่อาจถูกล็อค และจุดที่การสัมผัสควรเสร็จสิ้นภายในระยะเวลาที่กำหนด (เช่น การอัปเดตสถิติบางอย่าง) ในกรณีนี้ คุณสามารถใช้ LockBefore() หรือ TryLock() บางรูปแบบได้ ดูตัวอย่างสถิติด้านล่าง
/* Example 2: TryLock() for updating stats. */
func (s *StatsObject) updateObjStats(key, value interface{}) {
if s.someObj[key].TryLock() {
defer s.someObj[key].Unlock()
... update stats ...
... fill in s.cheapCachedResponse ...
}
}
func (s *StatsObject) UpdateStats() {
s.someObj.Range(s.updateObjStats)
}
เพื่อความสะดวกในการใช้งาน สมมติว่าในกรณีข้างต้น เรากำลังพูดถึง s.someObj เดียวกัน ออบเจ็กต์ใดๆ อาจถูกบล็อกโดยการดำเนินการ DoTheThing() เป็นเวลานาน ซึ่งหมายความว่าเราต้องการข้ามไปใน updateObjStats นอกจากนี้ เราต้องการให้แน่ใจว่าเราจะส่งคืนการตอบกลับราคาถูกใน DoTheThing() ในกรณีที่เราไม่สามารถรับการล็อคได้ทันเวลา
น่าเสียดายที่ sync.Mutex เท่านั้นและมีฟังก์ชัน Lock() และ Unlock() เท่านั้น ไม่มีทางที่จะอาจได้รับการล็อค มีวิธีง่ายๆ ในการทำเช่นนี้แทนหรือไม่? ฉันกำลังเผชิญกับปัญหาประเภทนี้จากมุมที่ผิดอย่างสิ้นเชิง และมีวิธีที่ "ไปสู่" ที่แตกต่างและมากกว่าในการแก้ปัญหาหรือไม่ หรือฉันจะต้องใช้ไลบรารี Mutex ของตัวเองหากต้องการแก้ไขปัญหาเหล่านี้ ฉันทราบถึง ฉบับที่ 6123 ซึ่งดูเหมือนว่าจะแนะนำว่าไม่มีสิ่งนั้นและ วิธีที่ฉันจัดการกับปัญหาเหล่านี้เป็นเรื่องที่ไม่เข้าท่าเลย