Vâng, nó phức tạp, nhưng có một vài quy tắc chung sẽ khiến mọi thứ trở nên đơn giản hơn nhiều.
- thích sử dụng các đối số chính thức cho các kênh bạn chuyển vào quy trình thay vì truy cập các kênh trong phạm vi toàn cầu. Bạn có thể kiểm tra trình biên dịch nhiều hơn theo cách này và mô đun tốt hơn.
- tránh cả việc đọc và viết trên cùng một kênh trong một quy trình cụ thể (bao gồm cả kênh 'chính'). Nếu không, bế tắc là một rủi ro lớn hơn nhiều.
Đây là phiên bản thay thế của chương trình của bạn, áp dụng hai nguyên tắc này. Trường hợp này chứng tỏ nhiều người viết và một người đọc trên một kênh:
c := make(chan string)
for i := 1; i <= 5; i++ {
go func(i int, co chan<- string) {
for j := 1; j <= 5; j++ {
co <- fmt.Sprintf("hi from %d.%d", i, j)
}
}(i, c)
}
for i := 1; i <= 25; i++ {
fmt.Println(<-c)
}
http://play.golang.org/p/quQn7xePLw
Nó tạo ra năm quy trình viết vào một kênh duy nhất, mỗi quy trình viết năm lần. Quy trình chính đọc tất cả 25 thông báo - bạn có thể nhận thấy rằng thứ tự chúng xuất hiện thường không theo trình tự (tức là sự đồng thời là hiển nhiên).
Ví dụ này cho thấy một đặc điểm của kênh cờ vây: có thể có nhiều người viết chia sẻ một kênh; Go sẽ tự động xen kẽ các tin nhắn.
Điều tương tự cũng áp dụng cho một người viết và nhiều người đọc trên một kênh, như được thấy trong ví dụ thứ hai ở đây:
c := make(chan int)
var w sync.WaitGroup
w.Add(5)
for i := 1; i <= 5; i++ {
go func(i int, ci <-chan int) {
j := 1
for v := range ci {
time.Sleep(time.Millisecond)
fmt.Printf("%d.%d got %d\n", i, j, v)
j += 1
}
w.Done()
}(i, c)
}
for i := 1; i <= 25; i++ {
c <- i
}
close(c)
w.Wait()
Ví dụ thứ hai này bao gồm một sự chờ đợi áp đặt đối với quy trình chính, nếu không thì quy trình này sẽ thoát ra ngoài kịp thời và khiến năm tuyến gorout khác bị kết thúc sớm (nhờ olov cho sự điều chỉnh này) .
Trong cả hai ví dụ, không cần bộ đệm. Nói chung, đó là một nguyên tắc tốt để xem bộ đệm chỉ như một công cụ nâng cao hiệu suất. Nếu chương trình của bạn không deadlock mà không có bộ đệm, thì nó cũng sẽ không bị deadlock với bộ đệm (nhưng điều ngược lại không phải lúc nào cũng đúng). Vì vậy, như một quy tắc chung khác, hãy bắt đầu mà không cần lưu vào bộ đệm, sau đó thêm nó vào sau khi cần .
original, hi from 4
...