Go Academy · บทเรียน

โมเดลหน่วยความจำของ Go และ Happens-Before

การรับประกันด้านการซิงโครไนซ์และลำดับหน่วยความจำ

บทเรียน 2 จาก 413 ขั้นตอน

โมเดลหน่วยความจำของ Go และ Happens-Before เป็นบทเรียน Go Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Go Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน

แบบจำลองหน่วยความจำคืออะไร

แบบจำลองหน่วยความจำของ Go กำหนดว่าเมื่อใดการเขียนค่าลงในตัวแปรโดย goroutine หนึ่ง จะรับประกันว่า goroutine อื่นจะมองเห็นค่าเมื่ออ่านตัวแปรนั้น หากไม่มีการรับประกันเหล่านี้ โปรแกรมที่ทำงานพร้อมกันอาจเห็นค่าที่ล้าสมัยหรือไม่สอดคล้องกัน

เกิดก่อน

ความสัมพันธ์แบบเกิดก่อนรับประกันว่าการเขียนทั้งหมดก่อนเหตุการณ์ A จะมองเห็นได้ที่เหตุการณ์ B หากไม่มีความสัมพันธ์แบบเกิดก่อน การอ่านอาจเห็นการเขียนใด ๆ รวมถึงค่าศูนย์

การรับประกันการเกิดก่อน: การเริ่ม goroutine

ทุกสิ่งที่เกิดขึ้นก่อนคำสั่ง go จะเกิดขึ้นก่อนฟังก์ชันของ goroutine เริ่มทำงาน goroutine ที่ถูกสร้างขึ้นจะมองเห็นการเขียนทั้งหมดที่เกิดขึ้นก่อนการสร้าง

x := 10
go func() {
    fmt.Println(x) // guaranteed to see 10
}()

การรับประกัน: การส่งและรับผ่านแชนเนล

การส่งผ่านแชนเนลจะเกิดขึ้นก่อนการรับที่สอดคล้องกัน การปิดแชนเนลจะเกิดขึ้นก่อนการรับค่าศูนย์ สิ่งเหล่านี้เป็นกลไกพื้นฐานสำหรับการประสานการทำงาน

ch := make(chan int)
go func() { ch <- 42 }()   // send hb receive
v := <-ch
fmt.Println(v) // guaranteed to see 42

การรับประกัน: sync.Mutex

การปลดล็อกมิวเทกซ์ครั้งที่ n จะเกิดขึ้นก่อนการล็อกครั้งที่ (n+1) ซึ่งรับประกันว่า goroutine ที่ล็อกหลังจากการปลดล็อกจะเห็นการเขียนทั้งหมดที่เกิดขึ้นก่อนการปลดล็อก

การรับประกัน: sync.Once

การทำงานเสร็จสิ้นของฟังก์ชัน once.Do จะเกิดขึ้นก่อนที่การเรียก once.Do ใด ๆ จะส่งคืนค่า goroutine ทั้งหมดที่เรียก once.Do จะเห็นการเริ่มต้นค่า

การรับประกัน: การปิดแชนเนล

การปิดแชนเนลจะเกิดขึ้นก่อนการรับที่ส่งคืนค่าศูนย์จากแชนเนลที่ปิดแล้ว นี่คือวิธีที่แชนเนล done ใช้ประกาศไปยัง goroutine หลายรายการ

ไม่มีการเกิดก่อน: ตัวแปรร่วมที่ไม่มีการป้องกัน

หาก goroutine สองรายการเข้าถึงตัวแปรโดยไม่มีการประสานการทำงาน และมีอย่างน้อยหนึ่งรายการเขียนค่า พฤติกรรมจะไม่ถูกกำหนด ตัวตรวจจับสภาวะแข่งขันจะตรวจพบกรณีนี้

การดำเนินการแบบอะตอมิก

แพ็กเกจ atomic มีการดำเนินการที่สอดคล้องกันตามลำดับ การจัดเก็บค่าแบบอะตอมิกจะเกิดขึ้นก่อนการโหลดค่าแบบอะตอมิกของตัวแปรเดียวกันใน goroutine ใด ๆ ที่มองเห็นค่าที่จัดเก็บ

แบบจำลองหน่วยความจำสำหรับแชนเนล

สำหรับแชนเนลแบบมีบัฟเฟอร์ที่มีความจุ C การรับครั้งที่ k จะเกิดขึ้นก่อนการส่งครั้งที่ (k+C) เสร็จสิ้น แบบจำลองนี้แสดงว่าความจุบัฟเฟอร์ที่จำกัดช่วยรับประกันแรงดันย้อนกลับ

กฎในทางปฏิบัติ

หากใช้ข้อมูลร่วมกันระหว่าง goroutine ให้ใช้แชนเนลเพื่อโอนความเป็นเจ้าของ หรือใช้มิวเทกซ์และการดำเนินการแบบอะตอมิกเพื่อป้องกันการอ่านและการเขียน อย่าอาศัยความเข้าใจโดยสัญชาตญาณเกี่ยวกับลำดับการทำงานโดยไม่มีการประสานการทำงาน

ตรวจสอบความเข้าใจ

ข้อใดต่อไปนี้สร้างความสัมพันธ์แบบเกิดก่อนระหว่าง goroutine

สรุป: แบบจำลองหน่วยความจำของ Go

ประเด็นสำคัญ:

  • การเกิดก่อนกำหนดว่าเมื่อใดการเขียนจะมองเห็นได้ระหว่าง goroutine
  • แชนเนล มิวเทกซ์ Once และการเริ่ม goroutine จะสร้างเส้นเชื่อมแบบ HB
  • การเข้าถึงสถานะที่เปลี่ยนแปลงได้ร่วมกันโดยไม่มีการประสานการทำงานเป็นพฤติกรรมที่ไม่ถูกกำหนด
  • ใช้ตัวตรวจจับสภาวะแข่งขันเพื่อตรวจจับการละเมิด
เริ่มต้นได้ฟรี

เรียนรู้ Go ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
51
บทเรียน
203

คำถามที่พบบ่อย

บทเรียน “โมเดลหน่วยความจำของ Go และ Happens-Before” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “โมเดลหน่วยความจำของ Go และ Happens-Before” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Go Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “โมเดลหน่วยความจำของ Go และ Happens-Before”

การรับประกันด้านการซิงโครไนซ์และลำดับหน่วยความจำ คุณปฏิบัติ Go Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Go Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Go Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “โมเดลหน่วยความจำของ Go และ Happens-Before” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Go Academy นี้ได้ไหม

ได้ บทเรียน Go Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

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

  1. สแตกกับฮีปและการวิเคราะห์การหลุดพ้น
  2. โมเดลหน่วยความจำของ Go และ Happens-Before
  3. ภายในตัวเก็บขยะ
  4. ลดการจัดสรร: sync.Pool และ Arena
← กลับไปที่ Go Academy