Go – Mutex

Mutex là hình thức ngắn gọn để loại trừ lẫn nhau. Mutex được sử dụng khi bạn không muốn một tài nguyên bị truy cập bởi nhiều Routine con trong cùng một thời điểm. Mutex có 2 phương thức Lock()Unlock(). Mutex được đặt trong package sync. Nên chúng ta phải import package sync. Các câu lệnh phải được thực hiên riêng rẽ lẫn nhau có thể được đặt trong mutex.Lock() hoặc mutex.Unlock(), do đó tránh được điều kiện Race.

Trong đoạn code bên trên x = x + 1 sẽ chỉ được chạy bởi một Goroutine tại bất cứ thời điểm nào do đó ngăn chặn được điều kiện Race.

Nếu một Goroutine nắm giữ lock (khoá) rồi và nếu một Goroutine mới đang cố gắng lấy được lock, thì Goroutine mới này sẽ đợi cho tợi khi Mutex được mở (unlock).

Hãy cùng xem ví dụ sau đây đếm số lần vòng lặp chạy. Trong chương trình này chúng ta mong đợi routine chạy vòng lặp 10 lần và count lưu trữ tổng số. Chúng ta gọi routine 3 lần nên tổng của nó nên là 30. count là biến global.

Đầu tiên, chạy chương trình không sử dụng Mutex

Kết quả

Kết quả chạy có thể khác bên trên nhưng sau cùng thì nó vẫn không là 30.

Ở đây điều đang xảy ra là 3 Goroutine  đang cố tăng vòng lặp và lưu vào trong biến count. Giả sử tại một thời điểm count đang là 5 và Goroutine1 sẽ tăng count lên 6, các bước xử lý như sau.

  1. Sao chép count vào temp
  2. Tăng giá trị temp
  3. Lưu temp ngược lại vào count

Giả sử ngay sau khi Goroutine1 thực hiện bước 3, Goroutine khác đang nắm giữ giá trị cũ là 3 theo các bước như trên và lưu lại giá trị là 4, nên kết quả bị sai.

Nào hãy thử chạy lại chương trình bên trên sử dụng Mutex

Kết quả

Như vậy chúng ta đã lấy được kết quả cuối cùng như mong đợi. Bởi vì các câu lệnh đọc, tăng, và ghi lại vào count được chạy trong Mutex.

You May Also Like

About the Author: Nguyen Dinh Thuc

Leave a Reply

avatar
  Subscribe  
Notify of