Tại sao đa luồng thường được ưa thích để cải thiện hiệu suất?


23

Tôi có một câu hỏi, đó là về lý do tại sao các lập trình viên dường như yêu thích các chương trình đồng thời và đa luồng nói chung.

Tôi đang xem xét 2 cách tiếp cận chính ở đây:

  • một cách tiếp cận không đồng bộ về cơ bản dựa trên các tín hiệu hoặc chỉ là một cách tiếp cận không đồng bộ như được gọi bởi nhiều giấy tờ và ngôn ngữ như C # 5.0 mới, và một "luồng đồng hành" quản lý chính sách của đường ống của bạn
  • một cách tiếp cận đồng thời hoặc tiếp cận đa luồng

Tôi sẽ chỉ nói rằng tôi đang nghĩ về phần cứng ở đây và trường hợp xấu nhất, và tôi đã tự mình thử nghiệm 2 mô hình này, mô hình async là một người chiến thắng ở điểm mà tôi không hiểu tại sao mọi người 90% thời gian nói về đa luồng khi họ muốn tăng tốc mọi thứ hoặc sử dụng tốt tài nguyên của họ.

Tôi đã thử nghiệm các chương trình đa luồng và chương trình không đồng bộ trên một máy cũ với lõi tứ Intel không cung cấp bộ điều khiển bộ nhớ bên trong CPU, bộ nhớ được quản lý hoàn toàn bởi bo mạch chủ, trong trường hợp này hiệu năng rất tệ với ứng dụng đa luồng, thậm chí số lượng luồng tương đối thấp như 3-4-5 có thể là một vấn đề, ứng dụng không phản hồi và chỉ chậm và khó chịu.

Mặt khác, một cách tiếp cận không đồng bộ tốt có lẽ không nhanh hơn nhưng cũng không tệ nhất, ứng dụng của tôi chỉ chờ kết quả và không bị treo, nó phản hồi nhanh và có một quy mô tốt hơn đang diễn ra.

Tôi cũng đã phát hiện ra rằng một sự thay đổi bối cảnh trong thế giới luồng không phải là rẻ trong kịch bản thế giới thực, nó thực sự khá tốn kém, đặc biệt là khi bạn có nhiều hơn 2 luồng cần phải xoay vòng và trao đổi lẫn nhau để được tính toán.

Trên các CPU hiện đại, tình hình không thực sự khác biệt, bộ điều khiển bộ nhớ được tích hợp nhưng quan điểm của tôi là CPU x86 về cơ bản là một máy nối tiếp và bộ điều khiển bộ nhớ hoạt động giống như với máy cũ có bộ điều khiển bộ nhớ ngoài trên bo mạch chủ . Bộ chuyển đổi ngữ cảnh vẫn là một chi phí có liên quan trong ứng dụng của tôi và thực tế là bộ điều khiển bộ nhớ được tích hợp hoặc CPU mới hơn có nhiều hơn 2 lõi, nó không phải là món hời đối với tôi.

Đối với những gì tôi đã trải nghiệm, cách tiếp cận đồng thời là tốt về mặt lý thuyết nhưng không tốt trong thực tế, với mô hình bộ nhớ được áp đặt bởi phần cứng, thật khó để sử dụng tốt mô hình này, nó cũng đưa ra rất nhiều vấn đề từ việc sử dụng cấu trúc dữ liệu của tôi để tham gia của nhiều chủ đề.

Ngoài ra cả hai mô hình không cung cấp bất kỳ khả năng bảo mật nào khi nhiệm vụ hoặc công việc sẽ được thực hiện trong một thời điểm nhất định, làm cho chúng thực sự giống nhau từ quan điểm chức năng.

Theo mô hình bộ nhớ X86, tại sao phần lớn mọi người đề nghị sử dụng đồng thời với C ++ và không chỉ là cách tiếp cận không đồng bộ? Ngoài ra tại sao không xem xét trường hợp xấu nhất của một máy tính trong đó bộ chuyển đổi ngữ cảnh có thể đắt hơn bản thân tính toán?


2
Một cách để so sánh là nhìn vào thế giới JavaScript, không có luồng và mọi thứ đều không đồng bộ, sử dụng các cuộc gọi lại. Nó hoạt động, nhưng nó có vấn đề riêng của nó.
Gort Robot

2
@StevenBurnap Bạn gọi nhân viên web là gì?
dùng16764

2
"thậm chí một số lượng chủ đề tương đối thấp như 3-4-5 có thể là một vấn đề, ứng dụng không phản hồi và chỉ chậm và khó chịu." => Có thể là do thiết kế kém / sử dụng chủ đề không phù hợp. Bạn thường thấy tình huống đó khi các luồng của bạn tiếp tục trao đổi dữ liệu, trong trường hợp đó, đa luồng có thể không phải là câu trả lời đúng hoặc bạn có thể cần phân vùng lại dữ liệu.
assylias

1
@assylias Để thấy sự chậm lại đáng kể trong luồng UI cho thấy số lượng khóa quá mức trên các luồng. Bạn có một triển khai kém hoặc bạn đang cố gắng đập một cái chốt vuông vào một cái lỗ tròn.
Evan Plaice

5
Bạn nói rằng "các lập trình viên dường như yêu thích các chương trình đồng thời và đa luồng nói chung" tôi nghi ngờ điều đó. Tôi sẽ nói "lập trình viên ghét nó" ... nhưng thường thì đó là điều hữu ích duy nhất để làm ...
johannes

Câu trả lời:


34

Bạn có nhiều lõi / nhân, sử dụng chúng

Async tốt nhất để thực hiện xử lý ràng buộc IO nặng nhưng xử lý ràng buộc CPU nặng thì sao?

Vấn đề phát sinh khi các khối mã đơn luồng (nghĩa là bị kẹt) trên một quy trình chạy dài. Ví dụ, hãy nhớ lại khi in tài liệu xử lý văn bản sẽ làm cho toàn bộ ứng dụng bị đóng băng cho đến khi công việc được gửi? Đóng băng ứng dụng là tác dụng phụ của việc chặn ứng dụng một luồng trong một tác vụ cần nhiều CPU.

Trong một ứng dụng đa luồng, các tác vụ chuyên sâu về CPU (ví dụ như lệnh in) có thể được gửi đến một luồng công nhân nền do đó giải phóng luồng UI.

Tương tự, trong một ứng dụng đa quy trình, công việc có thể được gửi qua tin nhắn (ví dụ IPC, ổ cắm, v.v.) đến một quy trình con được thiết kế riêng để xử lý công việc.

Trong thực tế, mã không đồng bộ và mã đa luồng / quy trình đều có những lợi ích và nhược điểm của chúng.

Bạn có thể thấy xu hướng trong các nền tảng đám mây chính, vì họ sẽ cung cấp các phiên bản chuyên biệt cho xử lý ràng buộc CPU và các phiên bản chuyên dùng cho xử lý ràng buộc IO.

Ví dụ:

  • Bộ nhớ (ví dụ Amazon S3, Google Cloud Drive) bị ràng buộc CPU
  • Máy chủ web bị ràng buộc IO (Amazon EC2, Google App Engine)
  • Cơ sở dữ liệu là cả hai, CPU bị ràng buộc để ghi / lập chỉ mục và IO bị ràng buộc để đọc

Để đặt nó vào quan điểm ...

Máy chủ web là một ví dụ hoàn hảo về nền tảng bị ràng buộc IO mạnh mẽ. Một máy chủ web đa luồng chỉ định một luồng cho mỗi kết nối sẽ không mở rộng tốt vì mỗi luồng phát sinh nhiều chi phí hơn do số lượng chuyển đổi ngữ cảnh và khóa luồng trên tài nguyên được chia sẻ tăng lên. Trong khi đó, một máy chủ web không đồng bộ sẽ sử dụng một không gian địa chỉ.

Tương tự như vậy, một ứng dụng chuyên dùng để mã hóa video sẽ hoạt động tốt hơn nhiều trong môi trường đa luồng vì quá trình xử lý nặng có liên quan sẽ khóa luồng chính cho đến khi hoàn thành công việc. Có nhiều cách để giảm thiểu điều này nhưng sẽ dễ dàng hơn nhiều khi có một luồng quản lý hàng đợi, luồng thứ hai quản lý dọn dẹp và nhóm luồng xử lý xử lý nặng. Giao tiếp giữa các luồng chỉ xảy ra khi các tác vụ được gán / hoàn thành để chi phí khóa luồng được giữ ở mức tối thiểu.

Ứng dụng tốt nhất thường sử dụng kết hợp cả hai. Chẳng hạn, một ứng dụng web có thể sử dụng nginx (tức là async đơn luồng) làm bộ cân bằng tải để quản lý torrent của các yêu cầu đến, một máy chủ web async tương tự (ví dụ Node.js) để xử lý các yêu cầu http và một bộ máy chủ đa luồng xử lý nội dung tải lên / truyền phát / mã hóa, v.v ...

Đã có rất nhiều cuộc chiến tôn giáo trong những năm qua giữa các mô hình đa luồng, đa tiến trình và không đồng bộ. Với hầu hết mọi thứ, câu trả lời tốt nhất thực sự nên là "nó phụ thuộc".

Nó đi theo cùng một dòng suy nghĩ biện minh cho việc sử dụng các kiến ​​trúc GPU và CPU song song. Hai hệ thống chuyên biệt chạy trong buổi hòa nhạc có thể có một cải tiến lớn hơn nhiều so với một cách tiếp cận nguyên khối duy nhất.

Không phải là tốt hơn bởi vì cả hai đều có công dụng của chúng. Sử dụng công cụ tốt nhất cho công việc.

Cập nhật:

Tôi đã xóa tham chiếu đến Apache và thực hiện một chỉnh sửa nhỏ. Apache sử dụng mô hình đa xử lý nhằm tạo ra một quy trình cho mọi yêu cầu làm tăng số lượng chuyển đổi ngữ cảnh ở cấp hạt nhân. Ngoài ra, do bộ nhớ không thể được chia sẻ qua các quy trình, mỗi yêu cầu phải chịu thêm chi phí bộ nhớ.

Đa luồng có xung quanh đòi hỏi bộ nhớ bổ sung vì nó phụ thuộc vào bộ nhớ dùng chung giữa các luồng. Bộ nhớ dùng chung sẽ loại bỏ chi phí bộ nhớ bổ sung nhưng vẫn phải chịu hình phạt khi chuyển đổi ngữ cảnh tăng. Ngoài ra - để đảm bảo rằng điều kiện cuộc đua không xảy ra - khóa luồng (đảm bảo quyền truy cập độc quyền chỉ một luồng duy nhất tại một thời điểm) được yêu cầu cho bất kỳ tài nguyên nào được chia sẻ trên các luồng.

Thật buồn cười khi bạn nói, "các lập trình viên dường như yêu thích các chương trình đồng thời và đa luồng nói chung." Lập trình đa luồng rất phổ biến bởi bất kỳ ai đã thực hiện bất kỳ số lượng đáng kể nào trong thời gian của họ. Khóa chết (một lỗi xảy ra khi tài nguyên bị khóa nhầm bởi hai nguồn khác nhau chặn cả hai khi kết thúc) và điều kiện cuộc đua (trong đó chương trình sẽ đưa ra kết quả sai ngẫu nhiên do trình tự không chính xác) là một trong những khó khăn nhất để theo dõi xuống và sửa chữa.

Cập nhật2:

Trái ngược với tuyên bố về việc IPC nhanh hơn truyền thông mạng (tức là ổ cắm). Không phải lúc nào cũng như vậy . Hãy nhớ rằng đây là những khái quát và chi tiết cụ thể về triển khai có thể có tác động rất lớn đến kết quả.


Tại sao một lập trình viên nên đi nhiều quá trình? Ý tôi là tôi cho rằng với hơn 1 tiến trình, bạn cũng cần một số loại giao tiếp giữa các quá trình có thể thêm một chi phí đáng kể, đây có phải là cách làm việc của lập trình viên Windows cũ không? Khi nào tôi nên đi nhiều quá trình? Cảm ơn bạn đã trả lời bằng cách này, hình ảnh thực sự tốt về những gì async và đa luồng là tốt cho.
dùng1849534

1
Bạn đang giả định rằng giao tiếp giữa các quá trình sẽ tăng tổng chi phí chung. Tuy nhiên, nếu trạng thái xử lý là bất biến, hoặc chỉ cần xử lý đồng bộ hóa khi bắt đầu / hoàn thành. nó có thể hiệu quả hơn nhiều khi quạt ra các nhiệm vụ song song hơn. Mẫu diễn viên là một ví dụ điển hình và nếu bạn chưa đọc về nó - nó thực sự đáng để đọc. akka.io
sylvanaar

1
@ user1849534 Nhiều luồng có thể nói chuyện với nhau thông qua bộ nhớ dùng chung + khóa hoặc IPC. Khóa dễ dàng hơn nhưng khó gỡ lỗi hơn nếu bạn mắc lỗi (ví dụ như khóa bị khóa, khóa chết). IPC là tốt nhất nếu bạn có nhiều luồng công nhân vì khóa không mở rộng tốt. Dù bằng cách nào, nếu bạn đang sử dụng một cách tiếp cận đa luồng, điều quan trọng là giữ cho giao tiếp / đồng bộ hóa giữa các luồng ở mức tối thiểu (nghĩa là để giảm thiểu chi phí).
Evan Plaice

1
@ akka.io Bạn hoàn toàn đúng. Tính không thay đổi là một cách để giảm thiểu / loại bỏ chi phí khóa nhưng bạn vẫn phải chịu chi phí thời gian cho việc chuyển đổi ngữ cảnh. Nếu bạn muốn mở rộng câu trả lời để bao gồm các chi tiết về mức độ bất biến có thể giải quyết các vấn đề đồng bộ hóa luồng, hãy thoải mái. Điểm chính mà tôi hướng đến là minh họa, có những trường hợp giao tiếp không đồng bộ có một lợi thế khác biệt so với đa luồng / tiến trình và ngược lại.
Evan Plaice

(cont) Nhưng, thành thật mà nói, nếu tôi cần nhiều khả năng xử lý ràng buộc CPU, tôi sẽ bỏ qua mô hình diễn viên và xây dựng nó để có khả năng mở rộng ra nhiều nút mạng. Giải pháp tốt nhất tôi thấy cho việc này là sử dụng mô hình máy thở nhiệm vụ của 0MQ trên các giao tiếp cấp ổ cắm. Xem hình 5 @ zguide.zeromq.org/page:all .
Evan Plaice

13

Cách tiếp cận không đồng bộ của Microsoft là một sự thay thế tốt cho các mục đích phổ biến nhất cho lập trình đa luồng: cải thiện khả năng đáp ứng đối với các tác vụ IO.

Tuy nhiên, điều quan trọng cần nhận ra là cách tiếp cận không đồng bộ hoàn toàn không có khả năng cải thiện hiệu năng hoặc cải thiện khả năng phản hồi đối với các tác vụ nặng của CPU.

Đa luồng cho phản hồi

Đa luồng cho khả năng đáp ứng là cách truyền thống để giữ cho chương trình phản hồi nhanh trong các tác vụ IO nặng hoặc các tác vụ tính toán nặng. Bạn lưu các tệp trên một luồng nền, để người dùng có thể tiếp tục công việc của họ mà không phải đợi ổ cứng hoàn thành nhiệm vụ. Luồng IO thường chặn chờ một phần của ghi để kết thúc, vì vậy các chuyển đổi ngữ cảnh là thường xuyên.

Tương tự, khi thực hiện một phép tính phức tạp, bạn muốn cho phép chuyển đổi ngữ cảnh thường xuyên để giao diện người dùng có thể vẫn phản hồi và người dùng không nghĩ rằng chương trình đã bị hỏng.

Nói chung, mục tiêu ở đây không phải là để có nhiều luồng chạy trên các CPU khác nhau. Thay vào đó, chúng tôi chỉ quan tâm đến việc chuyển đổi ngữ cảnh xảy ra giữa tác vụ nền chạy dài và giao diện người dùng, để UI có thể cập nhật và phản hồi cho người dùng trong khi tác vụ nền đang chạy. Nói chung, UI sẽ không chiếm nhiều năng lượng CPU và khung luồng hoặc HĐH thường sẽ quyết định chạy chúng trên cùng một CPU.

Chúng tôi thực sự mất hiệu năng tổng thể do chi phí chuyển đổi ngữ cảnh thêm, nhưng chúng tôi không quan tâm vì hiệu suất của CPU không phải là mục tiêu của chúng tôi. Chúng tôi biết rằng chúng tôi thường có nhiều năng lượng CPU hơn mức chúng tôi cần, và vì vậy mục tiêu của chúng tôi liên quan đến đa luồng là hoàn thành nhiệm vụ cho người dùng mà không lãng phí thời gian của người dùng.

Phương án "Không đồng bộ"

"Cách tiếp cận không đồng bộ" thay đổi hình ảnh này bằng cách cho phép chuyển đổi ngữ cảnh trong một luồng. Điều này đảm bảo rằng tất cả các tác vụ của chúng tôi sẽ chạy trên một CPU và có thể cung cấp một số cải tiến hiệu suất khiêm tốn về mặt tạo / dọn dẹp luồng ít hơn và ít chuyển đổi ngữ cảnh thực hơn giữa các luồng.

Thay vì tạo một luồng mới để chờ nhận tài nguyên mạng (ví dụ như tải xuống một hình ảnh), một asyncphương thức được sử dụng, đó awaitlà hình ảnh trở nên khả dụng, và trong khi đó, sẽ mang lại phương thức gọi.

Ưu điểm chính ở đây là bạn không phải lo lắng về các vấn đề luồng như tránh bế tắc, vì bạn hoàn toàn không sử dụng khóa và đồng bộ hóa, và có ít công việc hơn cho lập trình viên thiết lập luồng nền và quay lại trên luồng UI khi kết quả quay lại để cập nhật UI an toàn.

Tôi đã không nhìn quá sâu vào các chi tiết kỹ thuật, nhưng ấn tượng của tôi là việc quản lý tải xuống bằng hoạt động CPU nhẹ thỉnh thoảng trở thành một nhiệm vụ không phải cho một luồng riêng biệt, mà là một thứ giống như một nhiệm vụ trên hàng đợi sự kiện UI và khi tải xuống hoàn tất, phương thức không đồng bộ được nối lại từ hàng đợi sự kiện đó. Nói cách khác, awaitcó nghĩa là một cái gì đó giống như "kiểm tra xem kết quả tôi cần có sẵn hay không, nếu không, hãy đưa tôi trở lại hàng đợi nhiệm vụ của chủ đề này".

Lưu ý rằng phương pháp này sẽ không giải quyết được vấn đề của một tác vụ chuyên sâu về CPU: không có dữ liệu nào để chờ đợi, vì vậy chúng tôi không thể nhận được các chuyển đổi ngữ cảnh mà chúng tôi cần xảy ra mà không tạo ra một luồng xử lý nền thực tế. Tất nhiên, vẫn có thể thuận tiện khi sử dụng phương thức không đồng bộ để bắt đầu luồng nền và trả về kết quả, trong một chương trình sử dụng một cách phổ biến phương pháp không đồng bộ.

Đa luồng cho hiệu suất

Vì bạn nói về "hiệu suất", tôi cũng muốn thảo luận về cách đa luồng có thể được sử dụng để tăng hiệu suất, điều này hoàn toàn không thể với cách tiếp cận không đồng bộ đơn luồng.

Khi bạn thực sự ở trong một tình huống mà bạn không có đủ năng lượng CPU trên một CPU và muốn sử dụng đa luồng cho hiệu năng, điều đó thực sự rất khó thực hiện. Mặt khác, nếu một CPU không đủ sức mạnh xử lý, thì đó cũng thường là giải pháp duy nhất có thể cho phép chương trình của bạn thực hiện những gì bạn muốn thực hiện trong một khung thời gian hợp lý, đó là điều làm cho công việc trở nên đáng giá.

Song song tầm thường

Tất nhiên, đôi khi thể dễ dàng tăng tốc thực sự từ đa luồng.

Nếu bạn tình cờ có một số lượng lớn các tác vụ chuyên sâu tính toán độc lập (nghĩa là các tác vụ có dữ liệu đầu vào và đầu ra rất nhỏ đối với các phép tính phải được thực hiện để xác định kết quả), thì bạn thường có thể tăng tốc đáng kể bằng cách tạo một nhóm các luồng (có kích thước phù hợp dựa trên số lượng CPU có sẵn) và có một luồng chính phân phối công việc và thu thập kết quả.

Đa luồng thực tế cho hiệu suất

Tôi không muốn đưa mình về phía trước quá nhiều chuyên gia, nhưng ấn tượng của tôi là, nói chung, đa luồng thực tế nhất cho hiệu suất xảy ra ngày nay là tìm kiếm các vị trí trong một ứng dụng có tính song song tầm thường và sử dụng nhiều luồng để gặt hái những lợi ích.

Như với bất kỳ tối ưu hóa nào, tốt hơn hết là tối ưu hóa sau khi bạn định hình hiệu suất chương trình của mình và xác định các điểm nóng: dễ dàng làm chậm chương trình bằng cách quyết định tùy ý rằng phần này sẽ chạy trong một luồng và phần đó trong phần khác, mà không đầu tiên xác định xem cả hai phần có chiếm một phần đáng kể thời gian của CPU hay không.

Một luồng bổ sung có nghĩa là chi phí thiết lập / phá vỡ nhiều hơn và chuyển đổi ngữ cảnh nhiều hơn hoặc chi phí liên lạc giữa các CPU nhiều hơn. Nếu nó không hoạt động đủ để bù cho các chi phí đó nếu trên một CPU riêng biệt và không cần phải là một luồng riêng biệt vì lý do đáp ứng, nó sẽ làm mọi thứ chậm lại không có lợi.

Tìm kiếm các nhiệm vụ có ít phụ thuộc lẫn nhau và đang chiếm một phần đáng kể trong thời gian chạy chương trình của bạn.

Nếu chúng không có sự phụ thuộc lẫn nhau, thì đó là trường hợp song song không đáng kể, bạn có thể dễ dàng thiết lập từng chuỗi với một chuỗi và tận hưởng các lợi ích.

Nếu bạn có thể tìm thấy các tác vụ với sự phụ thuộc lẫn nhau hạn chế, do đó việc khóa và đồng bộ hóa để trao đổi thông tin không làm chậm đáng kể, thì đa luồng có thể tăng tốc, miễn là bạn cẩn thận để tránh các nguy cơ bế tắc do lỗi logic khi đồng bộ hóa hoặc kết quả không chính xác do không đồng bộ hóa khi cần thiết.

Ngoài ra, một số ứng dụng phổ biến hơn cho đa luồng không (tìm hiểu) để tăng tốc thuật toán được xác định trước, mà thay vào đó là ngân sách lớn hơn cho thuật toán mà họ dự định viết: nếu bạn đang viết một công cụ trò chơi và AI của bạn phải đưa ra quyết định trong tốc độ khung hình của bạn, bạn thường có thể cung cấp cho AI của mình ngân sách chu kỳ CPU lớn hơn nếu bạn có thể cung cấp cho CPU của chính nó.

Tuy nhiên, hãy chắc chắn để lập hồ sơ các chủ đề và đảm bảo rằng họ đang làm đủ công việc để bù đắp chi phí tại một số điểm.

Thuật toán song song

Ngoài ra còn có rất nhiều vấn đề có thể được xử lý bằng cách sử dụng nhiều bộ xử lý, nhưng nó quá nguyên khối để chỉ đơn giản là phân chia giữa các CPU.

Các thuật toán song song phải được phân tích cẩn thận cho thời gian hoạt động lớn nhất của chúng đối với thuật toán không song song tốt nhất hiện có, vì rất dễ dàng cho chi phí truyền thông giữa các CPU để loại bỏ bất kỳ lợi ích nào từ việc sử dụng nhiều CPU. Nói chung, họ phải sử dụng ít giao tiếp giữa các CPU (theo thuật ngữ big-O) hơn là họ sử dụng các tính toán trên mỗi CPU.

Hiện tại, nó vẫn chủ yếu là một không gian cho nghiên cứu học thuật, một phần là do yêu cầu phân tích phức tạp, một phần vì sự song song tầm thường khá phổ biến, một phần vì chúng ta chưa có quá nhiều lõi CPU trên máy tính của chúng ta. không thể giải quyết trong khung thời gian hợp lý trên một CPU có thể được giải trong khung thời gian hợp lý bằng cách sử dụng tất cả các CPU của chúng tôi.


+1 cho một câu trả lời rõ ràng cũng nghĩ ra. Mặc dù vậy, tôi vẫn nên thận trọng khi nhận các đề xuất của Microsoft theo mệnh giá. Hãy nhớ rằng .NET là một nền tảng đầu tiên đồng bộ, do đó, hệ sinh thái thiên vị trong việc cung cấp các phương tiện / tài liệu tốt hơn hỗ trợ xây dựng các giải pháp đồng bộ. Điều ngược lại sẽ đúng với các nền tảng đầu tiên không đồng bộ như Node.js.
Evan Plaice

3

ứng dụng không phản hồi và chỉ chậm và khó chịu.

Và có vấn đề của bạn. Một giao diện người dùng đáp ứng không tạo ra một ứng dụng biểu diễn. Thường thì ngược lại. Một loạt thời gian được dành để kiểm tra đầu vào UI thay vì để các luồng công nhân thực hiện công việc của họ.

Theo như 'chỉ' có một cách tiếp cận không đồng bộ, thì đó cũng là đa luồng cũng được điều chỉnh cho một trường hợp sử dụng cụ thể đó trong hầu hết các môi trường . Ở những người khác, sự không đồng bộ đó được thực hiện thông qua các coroutines ... không phải lúc nào cũng đồng thời.

Thành thật mà nói, tôi thấy các hoạt động không đồng bộ trở nên khó khăn hơn để suy luận và sử dụng theo cách thực sự mang lại lợi ích (hiệu suất, độ bền, khả năng bảo trì) thậm chí so với ... các cách tiếp cận thủ công hơn.


tại sao ? ví dụ những gì bạn tìm thấy chuối trong thư viện boost signal2?
dùng1849534
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.