Tôi đang gặp sự cố khi tìm hiểu cách sử dụng chính xác sync.Cond
. Từ những gì tôi có thể nói, một điều kiện chủng tộc tồn tại giữa khóa Locker và gọi phương thức Wait của điều kiện. Ví dụ này cho biết thêm một sự chậm trễ nhân tạo giữa hai dòng trong goroutine chính để mô phỏng các điều kiện chủng tộc:Cách sử dụng đúng cách sync.Cond?
package main
import (
"sync"
"time"
)
func main() {
m := sync.Mutex{}
c := sync.NewCond(&m)
go func() {
time.Sleep(1 * time.Second)
c.Broadcast()
}()
m.Lock()
time.Sleep(2 * time.Second)
c.Wait()
}
này gây ra hoảng loạn ngay lập tức:
fatal error: all goroutines are asleep - deadlock! goroutine 1 [semacquire]: sync.runtime_Syncsemacquire(0x10330208, 0x1) /usr/local/go/src/runtime/sema.go:241 +0x2e0 sync.(*Cond).Wait(0x10330200, 0x0) /usr/local/go/src/sync/cond.go:63 +0xe0 main.main() /tmp/sandbox301865429/main.go:17 +0x1a0
gì tôi đang làm sai à? Làm cách nào để tránh tình trạng cuộc đua rõ ràng này? Có một cấu trúc đồng bộ hóa tốt hơn tôi nên sử dụng?
Edit: Tôi nhận ra tôi nên có tốt hơn giải thích vấn đề tôi đang cố gắng để giải quyết đây. Tôi có một goroutine chạy dài tải xuống một tệp lớn và một số goroutine khác cần quyền truy cập vào các tiêu đề HTTP khi chúng có sẵn. Vấn đề này khó hơn âm thanh.
Tôi không thể sử dụng kênh vì chỉ một goroutine sau đó sẽ nhận được giá trị. Và một số goroutines khác sẽ cố gắng lấy lại các tiêu đề lâu sau khi chúng đã có sẵn.
Trình tải xuống goroutine có thể chỉ lưu trữ các tiêu đề HTTP trong một biến và sử dụng một mutex để bảo vệ quyền truy cập vào chúng. Tuy nhiên, điều này không cung cấp cách để các goroutines khác "chờ" để chúng trở nên khả dụng.
Tôi đã nghĩ rằng cả hai sync.Mutex
và sync.Cond
cùng nhau có thể đạt được mục tiêu này nhưng dường như điều này là không thể.
gì nếu nó không thể khóa mutex trước khi tung ra goroutine? Ví dụ, có thể có các goroutines khác gọi Wait(). –
Có thể, khi Broadcast được gọi, không có goroutine nào khác được thông báo. Nó cũng tốt - nhưng những gì cả hai chúng tôi không đề cập - thường tình trạng được kết nối với một số nhà nước. Và chờ đợi có nghĩa là - Tôi không thể tiếp tục trong khi hệ thống ở trạng thái này, chờ đợi. Và Broadcast nghĩa là - trạng thái bị thay đổi, mọi người đã chờ đợi nên kiểm tra xem liệu anh ấy có thể tiếp tục không. Vui lòng mô tả chính xác hơn những gì được tính trong cả hai goroutine, và tại sao chúng phải giao tiếp với nhau. – lofcek
Xin lỗi, tôi nên đi sâu vào chi tiết hơn trong câu hỏi ban đầu. Tôi đã thêm bản chỉnh sửa mô tả chính xác những gì tôi đang cố gắng làm. –