Sự khác nhau giữa "coroutine" và "thread" là gì?Sự khác biệt giữa "coroutine" và "thread"?
Trả lời
Coroutines là một dạng xử lý tuần tự: chỉ có một thực thi tại bất kỳ thời điểm nào (giống như các chương trình con AKA thực hiện các thủ tục AKA - chúng chỉ truyền lệnh cho nhau nhiều hơn).
Chủ đề (ít nhất là khái niệm) một dạng xử lý đồng thời: nhiều luồng có thể được thực hiện tại bất kỳ thời điểm nào. (Theo truyền thống, trên các CPU đơn, máy đơn lõi, đồng thời được mô phỏng với một số trợ giúp từ hệ điều hành - hiện nay, vì rất nhiều máy là đa CPU và/hoặc đa lõi, các chủ đề sẽ thực hiện de facto đồng thời, không chỉ "khái niệm").
Tùy thuộc vào ngôn ngữ bạn đang sử dụng. Ví dụ trong Lua they are the same thing (loại biến của một coroutine được gọi là thread
).
Thông thường mặc dù coroutines thực hiện tự nguyện năng suất nơi (bạn) lập trình viên quyết định nơi để yield
, tức là, cung cấp cho kiểm soát thói quen khác.
Các chủ đề thay vì được hệ điều hành tự động quản lý (dừng và khởi động) và thậm chí chúng có thể chạy cùng lúc trên các CPU đa lõi.
Trong một từ: preemption. Coroutines hành động như những kẻ buôn lậu để bàn giao cho nhau một điểm tập luyện tốt. Chủ đề (chủ đề thực) có thể bị gián đoạn tại hầu như bất kỳ điểm nào và sau đó được tiếp tục lại sau. Tất nhiên, điều này mang lại cho nó tất cả các loại vấn đề xung đột tài nguyên, do đó GIL khét tiếng - Global Interpreter Lock.
Nhiều triển khai chuỗi thực sự giống coroutines hơn.
Đầu đọc:Concurrency vs Parallelism - What is the difference?
Concurrency là sự tách biệt các nhiệm vụ để cung cấp xen kẽ thực hiện. Song song là việc thực hiện đồng thời nhiều phần công việc để tăng tốc độ. - https://github.com/servo/servo/wiki/Design
Câu trả lời ngắn: Với chủ đề, hệ điều hành chuyển sang chạy đề preemptively theo lịch trình của nó, đó là một thuật toán trong hạt nhân hệ điều hành. Với coroutines, lập trình viên và ngôn ngữ lập trình xác định khi nào chuyển đổi coroutines; nói cách khác, các tác vụ được hợp tác đa nhiệm bằng cách tạm dừng và tiếp tục các chức năng tại các điểm đã đặt, thông thường (nhưng không nhất thiết) trong một chuỗi đơn.
Long trả lời: Ngược lại với chủ đề, đó là trước emptively lên kế hoạch bởi các hệ điều hành, công tắc coroutine là hợp tác xã, có nghĩa là các lập trình viên (và có thể là ngôn ngữ lập trình và thời gian chạy của nó) điều khiển khi chuyển đổi sẽ xảy ra.
Ngược lại với chủ đề, trước khi làm trống, thiết bị chuyển mạch coroutine là hợp tác (điều khiển lập trình khi có chuyển đổi). Hạt nhân không tham gia vào các thiết bị chuyển mạch coroutine. - http://www.boost.org/doc/libs/1_55_0/libs/coroutine/doc/html/coroutine/overview.html
Một ngôn ngữ hỗ trợ đề bản địa có thể thực hiện chủ đề của nó (chủ đề người dùng) vào chủ đề của hệ điều hành (kernel đề). Mỗi tiến trình có ít nhất một luồng hạt nhân. Các luồng hạt giống như các tiến trình, ngoại trừ việc chúng chia sẻ không gian bộ nhớ trong quá trình của chúng với tất cả các luồng khác trong tiến trình đó. Một quá trình "sở hữu" tất cả các tài nguyên được gán của nó, như bộ nhớ, xử lý tệp, ổ cắm, xử lý thiết bị, v.v., và tất cả các tài nguyên này đều được chia sẻ giữa các luồng hạt nhân của nó.
Trình lên lịch hệ điều hành là một phần của hạt nhân chạy mỗi luồng trong một khoảng thời gian nhất định (trên một máy xử lý đơn lẻ). Scheduler phân bổ thời gian (timeslicing) cho mỗi thread, và nếu thread không được hoàn thành trong thời gian đó, thì scheduler sẽ kiểm tra trước nó (ngắt nó và chuyển sang một thread khác). Nhiều luồng có thể chạy song song trên một máy đa bộ xử lý, vì mỗi luồng có thể (nhưng không nhất thiết phải) được lên lịch trên một bộ xử lý riêng biệt.
Trên một máy xử lý đơn lẻ, các chủ đề được tính thời gian và được đặt trước (chuyển đổi giữa) một cách nhanh chóng (trên Linux, thời gian mặc định là 100ms) làm cho chúng đồng thời. Tuy nhiên, chúng không thể chạy song song (đồng thời), vì một bộ xử lý lõi đơn chỉ có thể chạy một thứ tại một thời điểm.
Coroutines và/hoặc máy phát điện có thể được sử dụng để thực hiện các chức năng hợp tác. Thay vì chạy trên các luồng hạt nhân và được lên lịch bởi hệ điều hành, chúng chạy trong một chuỗi duy nhất cho đến khi chúng sinh ra hoặc kết thúc, sinh ra các hàm khác được xác định bởi lập trình viên. Ngôn ngữ với máy phát điện, chẳng hạn như Python và ECMAScript 6, có thể được sử dụng để xây dựng coroutines. Async/await (nhìn thấy trong C#, Python, ECMAscript 7, Rust) là một sự trừu tượng được xây dựng trên các chức năng của máy phát điện có năng suất tương lai/hứa hẹn.
Trong một số hoàn cảnh, coroutines có thể tham khảo chức năng stackful khi phát có thể tham khảo chức năng Stackless.
Sợi, đề nhẹ và đề xanh là những cái tên khác cho coroutines hoặc điều coroutine-như thế nào. Đôi khi họ có thể nhìn (thường là về mục đích) giống như các luồng hệ điều hành trong ngôn ngữ lập trình, nhưng chúng không chạy song song như các luồng thực và làm việc thay vì giống như coroutine. (Có thể có những đặc điểm kỹ thuật cụ thể hơn hoặc khác biệt giữa các khái niệm này tùy thuộc vào ngôn ngữ hoặc triển khai.)
Ví dụ: Java có "chủ đề xanh"; đây là những chủ đề được lập kế hoạch bởi máy ảo Java (JVM) thay vì nguyên gốc trên các luồng hạt nhân của hệ điều hành bên dưới. Chúng không chạy song song hoặc tận dụng nhiều bộ xử lý/lõi - vì điều đó sẽ yêu cầu một chuỗi gốc! Vì chúng không được hệ điều hành lên lịch, chúng giống như coroutines hơn so với các luồng hạt nhân. Các luồng màu xanh là những gì Java được sử dụng cho đến khi các luồng gốc được đưa vào Java 1.2.
Chủ đề tiêu thụ tài nguyên. Trong JVM, mỗi luồng có ngăn xếp riêng, thường có kích thước 1MB. 64k là số lượng không gian ngăn xếp ít nhất được phép cho mỗi luồng trong JVM. Kích thước ngăn xếp luồng có thể được cấu hình trên dòng lệnh cho JVM. Mặc dù tên, các chủ đề không miễn phí, do các tài nguyên sử dụng của chúng như mỗi luồng cần ngăn xếp riêng, lưu trữ luồng cục bộ (nếu có) và chi phí lập lịch trình luồng/chuyển đổi bối cảnh/CPU bị mất hiệu lực.Đây là một phần lý do tại sao coroutines đã trở nên phổ biến cho các ứng dụng quan trọng, đồng thời cao.
Mac OS sẽ chỉ cho phép một quy trình phân bổ khoảng 2000 luồng và Linux phân bổ 8MB mỗi chuỗi và sẽ chỉ cho phép nhiều chuỗi phù hợp với RAM vật lý.
Do đó, chủ đề là trọng lượng nặng nhất (về mặt sử dụng bộ nhớ và thời gian chuyển ngữ cảnh), sau đó là coroutines và cuối cùng máy phát điện là trọng lượng nhẹ nhất.
Khoảng 7 năm sau, nhưng các câu trả lời ở đây thiếu một số ngữ cảnh về đồng chủ đề so với chủ đề. Tại sao coroutines nhận được nhiều sự chú ý gần đây và khi nào tôi sử dụng chúng so với chủ đề?
Trước hết, nếu coroutines chạy đồng thời (không bao giờ trong song song), tại sao mọi người lại thích chúng hơn chủ đề?
Câu trả lời là coroutines có thể cung cấp mức độ đồng thời rất cao với chi phí rất nhỏ. Nói chung trong môi trường luồng bạn có tối đa 30-50 luồng trước khi số lượng phí bị lãng phí thực sự lên lịch các luồng này (theo lịch trình hệ thống) đáng kể cắt giảm số lượng thời gian mà chuỗi thực sự thực hiện công việc hữu ích. Ok, với chủ đề bạn có thể có song song, nhưng không quá nhiều song song, không phải là vẫn còn tốt hơn so với một đồng thường xuyên chạy trong một chủ đề duy nhất? Không. Cũng không nhất thiết. Hãy nhớ rằng một đồng thường xuyên vẫn có thể thực hiện đồng thời mà không cần lên lịch trên đầu - nó chỉ đơn giản là quản lý việc chuyển đổi ngữ cảnh. Ví dụ nếu bạn có thói quen làm một số công việc và nó thực hiện một hoạt động bạn biết sẽ chặn một thời gian (tức là một yêu cầu mạng), với một đồng thường xuyên bạn có thể ngay lập tức chuyển sang một thói quen khác mà không có chi phí bao gồm bộ lập lịch hệ thống trong quyết định này - có bạn là người lập trình phải chỉ định khi nào các đồng nghiệp có thể chuyển đổi.
Với rất nhiều thói quen thực hiện rất ít công việc và tự nguyện chuyển đổi giữa nhau, bạn đã đạt đến mức hiệu quả mà không có người lập lịch nào có thể hy vọng đạt được. Bây giờ bạn có thể có hàng ngàn coroutines làm việc cùng nhau như trái ngược với hàng chục chủ đề.
Vì các thói quen của bạn bây giờ chuyển đổi giữa các điểm đã xác định trước, bạn có thể tránh khóa trên cấu trúc dữ liệu được chia sẻ (vì bạn sẽ không bao giờ yêu cầu mã của bạn chuyển sang một coroutine khác ở giữa phần quan trọng)
Lợi ích khác là mức sử dụng bộ nhớ thấp hơn nhiều. Với mô hình luồng, mỗi luồng cần phân bổ ngăn xếp của chính nó và do đó việc sử dụng bộ nhớ của bạn phát triển tuyến tính với số lượng chủ đề bạn có. Với các đồng nghiệp, số lượng các thói quen bạn có không có mối quan hệ trực tiếp với việc sử dụng bộ nhớ của bạn. Cuối cùng, đồng thường xuyên nhận được rất nhiều sự chú ý bởi vì trong một số ngôn ngữ lập trình (như Python), các luồng của bạn không thể chạy song song - chúng chạy đồng thời giống như coroutines, nhưng không có bộ nhớ thấp và miễn phí lên lịch.
Cách chuyển đổi sang loại khác nhiệm vụ trong coroutines khi chúng ta gặp phải một hoạt động chặn? –
Cách bạn chuyển sang tác vụ khác là có bất kỳ hoạt động chặn nào thực sự được thực hiện không đồng bộ. Điều này có nghĩa là bạn phải tránh sử dụng bất kỳ hoạt động nào thực sự chặn và chỉ sử dụng các hoạt động hỗ trợ không chặn khi được sử dụng trong hệ thống coroutine của bạn. Cách duy nhất xung quanh điều này là có coroutines được hỗ trợ bởi hạt nhân, chẳng hạn như UMS trên Windows chẳng hạn, nơi nó nhảy vào bộ lập lịch biểu của bạn bất cứ khi nào chuỗi UMS của bạn "" chặn trên syscall. – retep998
+1, nhưng câu trả lời này có thể được hưởng lợi từ một số tham chiếu. – kojiro
Chủ đề màu xanh lá cây là một số điều khác với coroutines. họ không?Ngay cả sợi có một số khác biệt. xem http://programmers.stackexchange.com/questions/254140/is-there-a-difference-between-fibers-coroutines-and-green-threads-and-if-that-i – penguin