2012-12-17 31 views
13

Dưới đây là một số nền:
Tôi cần một biến truy cập được chia sẻ giữa các thường trình đi, được sử dụng cho một thứ như thùng rò rỉ. Tôi biết có một ví dụ về rò rỉ-xô trong hiệu quả đi, phần đồng thời, nhưng số lượng mà tôi cần phải theo dõi có thể rất lớn, và tôi cảm thấy nó không hiệu quả để sử dụng số lượng các yếu tố trong một kênh để theo dõi nó. Vì vậy, tôi đang xem xét việc sử dụng một biến chia sẻ giữa các thói quen khác nhau để theo dõi số.Các toán tử gia tăng trong Go atomic trên x86?

Tôi hiểu rằng không có cấu hình rõ ràng, tất cả các thường trình sẽ được ánh xạ lên một chuỗi. Nhưng nếu tôi gán nhiều hơn một luồng cho chương trình trên một máy tính đa lõi, thì toán tử tăng có phải là nguyên tử không? Có giống nhau cho các loại dữ liệu khác nhau không (int32, float32, v.v.) trên các máy khác nhau (x86_32, x86_64, arm)?

Để cụ thể hơn, Điều gì sẽ xảy ra nếu tôi có counter += 1000 trong một thường lệ và counter -= 512 trong một thường trình khác, và hai quy trình sẽ xảy ra trong hai luồng? Tôi có cần phải lo lắng về chủ đề an toàn không? Tôi sẽ đặt trên ổ khóa trên counter?

Trả lời

16

Không, số gia tăng không bao giờ được giả định là nguyên tử. Sử dụng các hàm bổ sung nguyên tử hoặc một mutex.

Cho phép giả định:

import "sync/atomic" 
var counter = new(int32) 

Một goroutine thể làm atomic.AddInt32(counter, 1000) trong khi người khác đã làm atomic.AddInt32(counter, -512) mà không có một mutex.

Nếu bạn muốn sử dụng một mutex:

import "sync" 
var counter int32 
var mutex sync.Mutex 

func Add(x int32) { 
    mutex.Lock() 
    defer mutex.Unlock() 
    counter += x 
} 
+0

Wow. Cảm ơn! Tôi không nhận thấy có 'đồng bộ/nguyên tử'. Điều đó làm cho mọi thứ trở nên dễ dàng hơn nhiều! –

Các vấn đề liên quan