Skip to main content
goProgramming Language

รู้จักกับ Mutex ใน Golang คืออิหยัง หมดปัญหาเมื่อ Goroutine

ในบทความนี้จะพามารู้จักวิธีที่จะทำให้ Goroutines ใช้ข้อมูลตัวเดียวกัน แบบไม่ตีกันตายด้วย Mutex

เขียนโดย
Sirasit Boonklang – BorntoDev Co., Ltd.

Mutexes คือ ????

data structures ที่อยู่ใน sync package มันช่วยให้เราสามารถล็อคและปลดปลดล็อคข้อมูลเพื่อไม่ได้ให้เกิดความเสียหายจากการเข้าถึงข้อมูลพร้อมกัน เช่น การอ่านและเขียนในเวลาเดียวกันของคนละฟังก์ชัน ข้อมูลที่ได้อาจผิดพลาด

 

มาดูตัวอย่างกัน 

มาดูกันดีกว่าครับว่าทำไมเราต้องล็อคข้อมูลไว้ กลัวหายหรอ แล้วใครที่จะมาเอาไป คำตอบก็จะมาจากการที่ go สามารถใช้ goroutine ทำงานพร้อม ๆ กันในแต่ละฟังก์ชันได้ทำให้อาจเกิดเหตุการฟังก์ชันนึงเขียนข้อมูล อีกฟังก์ชันที่อ่านข้อมูลเข้าถึงข้อมูลตัวเดียวกันในเวลาพร้อมกัน

เราจะมาทำความเข้าใจทีละส่วนกัน

ส่วนแรกจะเป็นการใช้ package main ปกติสำหรับ go แล้วก็ import package ที่จำเป็นนั้นก็คือ sync และ fmt

  • fmt ย่อมากจาก format เป็น package สำหรับ ใช้ในการแสดงผล

  • sync เป็น package สำหรับใช้ในการจัดการ Mutex

 

ส่วนต่อมาจะเป็นการสร้างตัวแปรที่จำเป็นต่อการใช้งาน Mutex  

  • mutex  sync.Mutex คือ สร้างตัวแปร mutex ขึ้นมา ที่มีชนิดเป็น sync.Mutex

  • balance int สร้างตัวแปร balance ขึ้นมา โดยกำหนดชนิดข้อมูลเป็น int

 

func init() {} เป็นฟังก์ชันเริ่มต้นจะทำงานเพียงครั้งเดียวเท่านั้น โดยจะทำงานก่อนที่ฟังก์ชัน main() จะทำงาน โดยจากตัวอย่างนี้เราจะกำหนดให้เงินคงเหลือของเราเริ่มต้นที่ 1000 ในตัวแปร balance

 

ต่อมาจะสร้างฟังก์ชัน func deposit() ขึ้นมาค่ามาหนึ่งตัวซึ่งเป็น int โดยการทำงานของฟังก์ชัน deposit() มีดังนี้

  • mutex.Lock() เป็นการเพื่อกำหนด critical section ของโค้ด

  • defer mutex.Unlock เพื่อปลดล็อค critical section ของโค้ด แล้วมีการใส่ defer หน้าคำสั่ง เพื่อให้คำสั่งนี้ทำงานเมื่อฟังก์ชัน deposit() ทำงานเสร็จสิ้น

  • แล้วก็แสดงผลค่าที่จะฝากเข้าบัญชี 

  • balance += value บวกค่าที่จะฝากเข้าบัญชีเข้าไปในตัวแปร balance

  • fmt.Println(“”)   แสดงผลบรรทัดว่าง

 

สุดท้ายจะเป็นฟังก์ชัน mian() ซึ่งเป็นฟังก์ชันการทำงานหลัก โดยเราจะสร้างตัวแปร wg ขึ้นมา โดยใช้คำสั่ง sync.WaitGroup สำหรับตัวแปร wg จะใช้ในการจัดการการทำงานของ Goroutine และจะเป็นตัวนับจำนวน Goroutine ที่กำลังทำงานอยู่ โดยจะเริ่มต้นทำงานด้วยค่า 0 และจะเพิ่มค่าขึ้นเมื่อมี Goroutine ทำงาน โดยใช้คำสั่ง wg.Add(1) จะลดค่าลงเมื่อ Goroutine ทำงานเสร็จสิ้น โดยใช้คำสั่ง wg.Done() จะทำการรอ Goroutine ทำงานเสร็จสิ้น โดยใช้คำสั่ง wg.Wait()


จากโค้ดการทำงานในฟังก์ชัน main() 

  • var wg sync.WaitGroup เป็นการประกาศตัวแปร wg จะใช้ในการจัดการการทำงานของ Goroutine

  • wg.Add(2)  จะเพิ่มค่าขึ้นเมื่อมี Goroutine ทำงานในที่นี้มี 2 goroutines

  • fmt.Println(“Start Balance : “, balance) แสดงค่าของตัวแปร balance ก่อนทำการฝากเงิน

  • แล้วเราก็ทำการสร้าง Goroutine ขึ้นมา โดยใช้คำสั่งดังนี้

 

จากตัวอย่าง Goroutine ที่ทำงานพร้อมกันคือฝากเงิน 200 และ 100 และเมื่อ routine ไหนทำงานเสร็จทำการลดค่าของตัวแปร wg ลง 1 ค่าจากคำสั่ง wg.Done()

 

หลังจากนั้นจะใช้คำสั่ง wg.Wait() เพื่อรอ Goroutine ทำงานเสร็จสิ้น แล้วทำการแสดงค่าของตัวแปร balance หลังทำการฝากเงินด้วยคำสั่ง fmt.Println(“Final Balance : “, balance)

สำหรับผลลัพธ์ที่ได้จะเป็นดังนี้

 

จะเห็นได้ว่าค่าในส่วนของ balance เมื่อฝาก 100 ไปค่าใน balance ก็จะยังอยู่ที่ 1000 เท่าเดิมในเวลาเดียวกันกับที่เพิ่มค่า 200 เข้าใน balance ทำให้การเข้าถึงข้อมูลในเวลาเดียวกันอาจจะเกิดข้อผิดพลาดขึ้นได้

 

Ref. Using a Mutex in Go (Golang) – with Examples (sohamkamani.com)

หากคุณสนใจพัฒนา สตาร์ทอัพ แอปพลิเคชัน
และ เทคโนโลยีของตัวเอง ?

อย่ารอช้า ! เรียนรู้ทักษะด้านดิจิทัลเพื่ออัพเกรดความสามารถของคุณ
เริ่มตั้งแต่พื้นฐาน พร้อมปฏิบัติจริงในรูปแบบหลักสูตรออนไลน์วันนี้

BorntoDev

Author BorntoDev

BorntoDev Co., Ltd.

More posts by BorntoDev

เราใช้คุกกี้เพื่อพัฒนาประสิทธิภาพ และประสบการณ์ที่ดีในการใช้เว็บไซต์ของคุณ คุณสามารถศึกษารายละเอียดได้ที่ นโยบายความเป็นส่วนตัว และสามารถจัดการความเป็นส่วนตัวเองได้ของคุณได้เองโดยคลิกที่ ตั้งค่า

ตั้งค่าความเป็นส่วนตัว

คุณสามารถเลือกการตั้งค่าคุกกี้โดยเปิด/ปิด คุกกี้ในแต่ละประเภทได้ตามความต้องการ ยกเว้น คุกกี้ที่จำเป็น

ยอมรับทั้งหมด
จัดการความเป็นส่วนตัว
  • คุกกี้ที่จำเป็น
    เปิดใช้งานตลอด

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

  • คุกกี้สำหรับการติดตามทางการตลาด

    ประเภทของคุกกี้ที่มีความจำเป็นในการใช้งานเพื่อการวิเคราะห์ และ นำเสนอโปรโมชัน สินค้า รวมถึงหลักสูตรฟรี และ สิทธิพิเศษต่าง ๆ คุณสามารถเลือกปิดคุกกี้ประเภทนี้ได้โดยไม่ส่งผลต่อการทำงานหลัก เว้นแต่การนำเสนอโปรโมชันที่อาจไม่ตรงกับความต้องการ
    รายละเอียดคุกกี้

บันทึกการตั้งค่า