Tôi chỉ là một người dùng Go bình thường, vì vậy hãy dùng những hạt muối sau đây.
Wikipedia định nghĩa các luồng màu xanh lá cây là "các luồng được lên lịch bởi một máy ảo (VM) thay vì nguyên bản bởi hệ điều hành bên dưới". Các luồng xanh mô phỏng các môi trường đa luồng mà không cần dựa vào bất kỳ khả năng nào của hệ điều hành gốc và chúng được quản lý trong không gian người dùng thay vì không gian kernel, cho phép chúng hoạt động trong các môi trường không có hỗ trợ luồng gốc.
Go (hay chính xác hơn là hai triển khai hiện có) là ngôn ngữ chỉ tạo mã gốc - nó không sử dụng VM. Hơn nữa, bộ lập lịch trong các triển khai thời gian chạy hiện tại phụ thuộc vào các luồng mức hệ điều hành (ngay cả khi GOMAXPROCS = 1). Vì vậy, tôi nghĩ rằng việc nói về các chủ đề màu xanh lá cây cho mô hình Go là một chút lạm dụng.
Mọi người đã đặt ra thuật ngữ goroutine đặc biệt là để tránh nhầm lẫn với các cơ chế tương tranh khác (như coroutines hoặc thread hoặc các quy trình nhẹ).
Tất nhiên, Go hỗ trợ mô hình luồng M: N, nhưng nó trông gần với mô hình quá trình Erlang hơn là mô hình luồng xanh Java.
Dưới đây là một vài lợi ích của mô hình Go so với các luồng màu xanh lá cây (như được triển khai trong JVM sớm):
Nhiều lõi hoặc CPU có thể được sử dụng một cách hiệu quả, một cách minh bạch cho nhà phát triển. Với Go, nhà phát triển nên quan tâm đến sự tương tranh. Thời gian chạy Go sẽ chăm sóc song song. Việc triển khai các luồng xanh của Java không mở rộng trên nhiều lõi hoặc CPU.
Các cuộc gọi hệ thống và C không chặn đối với bộ lập lịch (tất cả các cuộc gọi hệ thống, không chỉ các cuộc gọi hỗ trợ I / O đa kênh trong các vòng lặp sự kiện). Việc triển khai các luồng xanh có thể chặn toàn bộ quá trình khi một cuộc gọi hệ thống chặn được thực hiện.
Sao chép hoặc phân đoạn ngăn xếp. Trong Go, không cần cung cấp kích thước ngăn xếp tối đa cho con goroutine. Các ngăn xếp tăng dần khi cần thiết. Một hậu quả là một con goroutine không cần nhiều bộ nhớ (4KB-8KB), vì vậy một số lượng lớn trong số chúng có thể được sinh ra một cách vui vẻ. Do đó sử dụng Goroutine có thể phổ biến.
Bây giờ, để giải quyết những lời chỉ trích:
Với Go, bạn không phải viết lịch trình không gian người dùng: nó đã được cung cấp với thời gian chạy. Nó là một phần mềm phức tạp, nhưng đó là vấn đề của các nhà phát triển Go, không phải của người dùng Go. Cách sử dụng của nó là minh bạch cho người dùng Go. Trong số các nhà phát triển Go, Dmitri Vyukov là một chuyên gia về lập trình lockfree / Waitfree và anh ta dường như đặc biệt quan tâm đến việc giải quyết các vấn đề hiệu suất cuối cùng của bộ lập lịch. Việc thực hiện lập lịch hiện tại không hoàn hảo, nhưng nó sẽ được cải thiện.
Đồng bộ hóa mang lại vấn đề về hiệu năng và độ phức tạp: điều này cũng đúng một phần với Go. Nhưng lưu ý, mô hình Go cố gắng thúc đẩy việc sử dụng các kênh và phân tách sạch chương trình trong các con khỉ đột đồng thời để hạn chế sự phức tạp đồng bộ hóa (tức là chia sẻ dữ liệu bằng cách giao tiếp, thay vì chia sẻ bộ nhớ để giao tiếp). Nhân tiện, việc triển khai Go tham chiếu cung cấp một số công cụ để giải quyết các vấn đề về hiệu năng và đồng thời, như trình lược tả và trình phát hiện cuộc đua .
Liên quan đến lỗi trang và "giả mạo nhiều luồng", xin lưu ý Go có thể lên lịch trình goroutine qua nhiều luồng hệ thống. Khi một luồng bị chặn vì bất kỳ lý do nào (lỗi trang, chặn các cuộc gọi hệ thống), nó không ngăn các luồng khác tiếp tục lên lịch và chạy các con khỉ đột khác. Bây giờ, đúng là một lỗi trang sẽ chặn luồng hệ điều hành, với tất cả các con khỉ đột được cho là đã được lên lịch trên luồng này. Tuy nhiên, trong thực tế, bộ nhớ heap Go không bị tráo đổi. Điều này cũng tương tự trong Java: dù sao ngôn ngữ được thu gom rác cũng không chứa được bộ nhớ ảo. Nếu chương trình của bạn phải xử lý lỗi trang một cách duyên dáng, nếu có thể vì nó phải quản lý một số bộ nhớ heap. Trong trường hợp đó,
Vì vậy, IMO, khỉ đột không phải là chủ đề xanh, và ngôn ngữ Go và việc triển khai hiện tại chủ yếu giải quyết những chỉ trích này.