Tại sao không thể tìm nạp giá trị trả về từ một chương trình goroutine gán nó cho một biến?
Chạy goroutine (không đồng bộ) và tìm nạp giá trị trả về từ hàm về cơ bản là các hành động trái ngược nhau. Khi bạn nói go
ý bạn là "làm điều đó không đồng bộ" hoặc đơn giản hơn: "Tiếp tục! Đừng đợi quá trình thực thi hàm kết thúc". Nhưng khi bạn gán giá trị trả về của hàm cho một biến, bạn đang mong đợi giá trị này trong biến đó. Vì vậy, khi bạn làm điều đó, x := go doSomething(arg)
bạn đang nói: "Tiếp tục, đừng đợi hàm! Chờ-đợi-đợi! Tôi cần một giá trị trả về có thể truy cập được trong x
var ngay ở dòng tiếp theo bên dưới!"
Kênh truyền hình
Cách tự nhiên nhất để tìm nạp một giá trị từ một quy trình là các kênh. Kênh là các đường ống kết nối các tuyến sinh dục đồng thời. Bạn có thể gửi các giá trị vào các kênh từ một quy trình và nhận các giá trị đó vào một quy trình khác hoặc trong một hàm đồng bộ. Bạn có thể dễ dàng lấy một giá trị từ một quy trình không phá vỡ tính tương tranh bằng cách sử dụng select
:
func main() {
c1 := make(chan string)
c2 := make(chan string)
go func() {
time.Sleep(time.Second * 1)
c1 <- "one"
}()
go func() {
time.Sleep(time.Second * 2)
c2 <- "two"
}()
for i := 0; i < 2; i++ {
select {
case msg1 := <-c1:
fmt.Println("received", msg1)
case msg2 := <-c2:
fmt.Println("received", msg2)
}
}
}
Ví dụ được lấy từ Go By Example
CSP & chuyển tin nhắn
Go lớn hơn là dựa trên lý thuyết CSP . Mô tả ngây thơ ở trên có thể được phác thảo chính xác về CSP (mặc dù tôi tin rằng nó nằm ngoài phạm vi của câu hỏi). Tôi thực sự khuyên bạn nên làm quen với lý thuyết CSP ít nhất vì nó là RAD. Những câu danh ngôn ngắn này đưa ra một hướng suy nghĩ:
Như tên gọi của nó, CSP cho phép mô tả hệ thống dưới dạng các quy trình thành phần hoạt động độc lập và tương tác với nhau duy nhất thông qua giao tiếp truyền thông điệp .
Trong khoa học máy tính, truyền thông điệp sẽ gửi thông điệp đến một quy trình và dựa vào quy trình và cơ sở hạ tầng hỗ trợ để chọn và gọi mã thực tế để chạy. Truyền thông điệp khác với lập trình thông thường trong đó một tiến trình, chương trình con hoặc hàm được gọi trực tiếp bằng tên.