- vừa được xem lúc

[Golang] Tìm Hiểu Sync.Cond trong Golang

0 0 21

Người đăng: Open Dev

Theo Viblo Asia

  • theo định nghĩa, event là bất kì tính hiệu nào giữa 2 hoặc nhiều goroutine mà thực tế nó đã xảy ra. Thông thường bạn sẽ muốn một đợi một tính hiệu trước khi thực hiện một goroutine khác. Nếu chúng ta xem xét để thực hiện điều này mà ko dùng Cond thì đơn giản là dùng vòng lặp vô tận.
for conditionTrue() == false { time.Sleep(1*time.Millisecond)
}
  • Cách giải quyết này cũng tốt, nhưng thực sự là sẽ không hiệu quả, bời vì bạn phải tìm ra thời gian để cấu hình hàm sleep. Nếu sleep quá lâu thì sẽ ảnh hưởng đến performance, còn nếu quá ngắn sẽ thì sẽ tốn thời gian của CPU một cách không cần thiết. Nó sẽ tốt nếu có một loại function hoặc cách gì đó mà goroutine có thể sleep cho đến khi có 1 tín hiệu thực thi. Và Cond sẽ giúp thực thi điều đó.

các function trong cond:

  • NewCond:
func NewCond(l Locker) *Cond // Create a new Cond conditional variable.
  • Broadcast
func (c *Cond) Broadcast() // Broadcast will wake up all goroutines waiting for c.
// Broadcast can be called with or without locking.
  • Signal:
func (c *Cond) Signal() // Signal wakes up only 1 goroutine waiting for c.
// Signal can be called with or without locking.
  • Wait:
func (c *Cond) Wait()
// does not return unless it is woken up by Signal or Broadcast.
  • Sử dụng Cond để viết một ví dụ đơn giản trước:
c := sync.NewCond(&sync.Mutex{}) // (1) new cond instantiate, func NewCond sẽ đáp ứng sync.Locker
c.L.Lock() // (2) Lock process
for conditionTrue() == false { c.Wait() // (3) chúng ta sẽ đợi khi có một thông báo điều kiện được xả ra. Và sẽ block tất cả các goroutine khác.
}
c.L.Unlock() // (4) UnLock process
  • Cách tiếp cận này là hiệu quả hơn. Ghi chú, func Wait không chỉ block, nó còn treo goroutine hiện tại, và cho phép các goroutine khác vẫn chạy trên OS thread.
  • Để giải thích thêm, xem thêm ví dụ sau:
func CondExample1() { c := sync.NewCond(&sync.Mutex{}) queue := make([]int, 0, 10) removeFromQueue := func(delay time.Duration, i int) { time.Sleep(delay) c.L.Lock() fmt.Println("before remove:", queue) queue = queue[1:] fmt.Println("after remove:", queue) c.L.Unlock() c.Signal() } for i := 0; i < 10; i++ { fmt.Println("start loop;", i) c.L.Lock() for len(queue) == 2 { fmt.Println("len equal 2, waiting", i) c.Wait() } fmt.Println("Adding to queue", i) queue = append(queue, i) go removeFromQueue(1*time.Second, i) c.L.Unlock() fmt.Println() } fmt.Println("after processing, len queue:", len(queue), queue)
}
  • output:
start loop; 0
Adding to queue 0 start loop; 1
Adding to queue 1 start loop; 2
len equal 2, waiting 2
before remove: [0 1]
after remove: [1]
Adding to queue 2 start loop; 3
len equal 2, waiting 3
before remove: [1 2]
after remove: [2]
Adding to queue 3 start loop; 4
len equal 2, waiting 4
before remove: [2 3]
after remove: [3]
Adding to queue 4 start loop; 5
len equal 2, waiting 5
before remove: [3 4]
after remove: [4]
Adding to queue 5 start loop; 6
len equal 2, waiting 6
before remove: [4 5]
after remove: [5]
Adding to queue 6 start loop; 7
before remove: [5 6]
after remove: [6]
Adding to queue 7 start loop; 8
len equal 2, waiting 8
before remove: [6 7]
after remove: [7]
Adding to queue 8 start loop; 9
len equal 2, waiting 9
before remove: [7 8]
after remove: [8]
Adding to queue 9 after processing, len queue: 2 [8 9]
  • Như kết quả, thì chương trình đã add 10 item đến queue, nhưng nó luôn luôn đợi cho cho 1 item được dequeue trước khi enqueue một item khác
  • Trong ví dụ có một function Signal, nó là một method mà Cond cung cấp để notifying một goroutine đã được block trên wait trước đó.

Bình luận

Bài viết tương tự

- vừa được xem lúc

gRPC - Nó là gì và có nên sử dụng hay không?

Nhân một ngày rảnh rỗi, mình ngồi đọc lại RPC cũng như gRPC viết lại để nhớ lâu hơn. Vấn đề là gì và tại sao cần nó .

0 0 132

- vừa được xem lúc

Embedded Template in Go

Getting Start. Part of developing a web application usually revolves around working with HTML as user interface.

0 0 57

- vừa được xem lúc

Tạo Resful API đơn giản với Echo framework và MySQL

1. Giới thiệu.

0 0 61

- vừa được xem lúc

Sử dụng goquery trong golang để crawler thông tin các website Việt Nam bị deface trên mirror-h.org

. Trong bài viết này, mình sẽ cùng mọi người khám phá một package thu thập dữ liệu có tên là goquery của golang. Mục tiêu chính của chương trình crawler này sẽ là lấy thông tin các website Việt Nam bị deface (là tấn công, phá hoại website, làm thay đổi giao diện hiển thị của một trang web, khi người

0 0 237

- vừa được xem lúc

Tạo ứng dụng craw dữ liệu bing với Golang, Mysql driver

Chào mọi người . Lâu lâu ta lại gặp nhau 1 lần, để tiếp tục series chia sẻ kiến thức về tech, hôm nay mình sẽ tìm hiểu và chia sẻ về 1 ngôn ngữ đang khá hot trong cộng đồng IT đó là Golang.

0 0 76

- vừa được xem lúc

Golang: Rest api and routing using MUX

Routing with MUX. Let's create a simple CRUD api for a blog site. # All . GET articles/ .

0 0 55