Chủ đề so với Async


81

Tôi đã đọc về mô hình lập trình phân luồng so với mô hình không đồng bộ từ bài viết thực sự hay này. http://krondo.com/blog/?p=1209

Tuy nhiên, bài báo đề cập đến những điểm sau.

  1. Một chương trình không đồng bộ sẽ đơn giản hoạt động tốt hơn một chương trình đồng bộ bằng cách chuyển đổi giữa các tác vụ bất cứ khi nào có I / O.
  2. Chủ đề được quản lý bởi hệ điều hành.

Tôi nhớ đã đọc rằng các luồng được quản lý bởi hệ điều hành bằng cách di chuyển xung quanh các TCB giữa Hàng đợi sẵn sàng và Hàng đợi chờ (trong số các hàng đợi khác). Trong trường hợp này, các chủ đề cũng không lãng phí thời gian chờ đợi phải không?

Dựa trên những điều đã đề cập ở trên, những ưu điểm của chương trình không đồng bộ so với chương trình phân luồng là gì?


5
Không, ý tôi là Threaded so với Async. Tôi đề cập đến điểm một chỉ vì đó là điều tôi hiểu được từ bài báo.

Câu trả lời:


78
  1. Rất khó để viết mã an toàn cho luồng. Với mã không đồng bộ, bạn biết chính xác nơi mã sẽ chuyển từ nhiệm vụ này sang nhiệm vụ tiếp theo và các điều kiện đua do đó khó xảy ra hơn nhiều.
  2. Các luồng sử dụng một lượng dữ liệu hợp lý vì mỗi luồng cần phải có ngăn xếp riêng. Với mã không đồng bộ, tất cả mã chia sẻ cùng một ngăn xếp và ngăn xếp được giữ nhỏ do liên tục tháo ngăn xếp giữa các tác vụ.
  3. Chủ đề là cấu trúc hệ điều hành và do đó có nhiều bộ nhớ hơn cho nền tảng hỗ trợ. Không có vấn đề như vậy với các tác vụ không đồng bộ.

12
Nói rõ hơn một chút: 1. Phần I / O của mã luồng tương đối dễ dàng nhưng việc quản lý trạng thái chia sẻ giữa các luồng (sử dụng khóa / hàng đợi / v.v.) mà không có điều kiện chủng tộc là điều khiến nó trở nên phức tạp. Sử dụng mô hình không đồng bộ có nghĩa là bạn sẽ ít diễn ra cùng một lúc nên dễ dàng tránh được các cuộc đua. 2/3. mỗi luồng sẽ sử dụng ít nhất một trang bộ nhớ của ngăn xếp (thường là 4KB hoặc 8KB), cộng với một số lượng bộ nhớ không xác định cho các cấu trúc dữ liệu khác liên quan đến trạng thái của luồng đó.
Dobes Vandermeer,

12

Có hai cách để tạo chuỗi:

luồng đồng bộ - cha tạo một (hoặc nhiều) luồng con và sau đó phải đợi mỗi luồng con kết thúc. Phân luồng đồng bộ thường được gọi là mô hình nối nhánh .

luồng không đồng bộ - cha và con chạy đồng thời / độc lập với nhau. Máy chủ đa luồng thường tuân theo mô hình này.

tài nguyên - http://www.amazon.com/Operating-System-Conformation-Abraham-Silberschatz/dp/0470128720


7
  1. Giả sử bạn có 2 tác vụ không liên quan đến bất kỳ IO nào (trên máy đa xử lý). Trong trường hợp này, các luồng hoạt động tốt hơn Async. Bởi vì Async giống như một chương trình đơn luồng thực thi các tác vụ của bạn theo thứ tự. Nhưng các luồng có thể thực hiện đồng thời cả hai tác vụ.

  2. Giả sử bạn có 2 nhiệm vụ, liên quan đến IO (trên máy đa xử lý). Trong trường hợp này, cả Async và Threads đều hoạt động ít nhiều giống nhau (hiệu suất có thể thay đổi dựa trên số lượng lõi, lập lịch, mức độ chuyên sâu của quy trình mà tác vụ thực hiện, v.v.). Ngoài ra Async chiếm ít tài nguyên hơn, chi phí thấp và ít phức tạp hơn để lập trình qua chương trình đa luồng.

Làm thế nào nó hoạt động? Luồng 1 thực hiện Nhiệm vụ 1, vì nó đang đợi IO, nó được chuyển đến Hàng đợi IO. Tương tự, Luồng 2 thực hiện Nhiệm vụ 2, vì nó cũng liên quan đến IO nên nó được chuyển đến Hàng đợi IO. Ngay sau khi yêu cầu IO của nó được giải quyết, nó sẽ được chuyển đến hàng đợi sẵn sàng để bộ lập lịch có thể lên lịch cho luồng thực thi.

Async thực hiện Nhiệm vụ 1 và không đợi IO của nó hoàn thành, nó tiếp tục với Nhiệm vụ 2 sau đó nó đợi IO của cả hai nhiệm vụ hoàn thành. Nó hoàn thành các nhiệm vụ theo thứ tự hoàn thành IO.

Không đồng bộ phù hợp nhất cho các tác vụ liên quan đến cuộc gọi dịch vụ Web, cuộc gọi truy vấn cơ sở dữ liệu, v.v., Chủ đề cho các tác vụ quy trình chuyên sâu.

Video dưới đây giải thích về Async vs Threaded modelvà cũng như thời điểm sử dụng, v.v., https://www.youtube.com/watch?v=kdzL3r-yJZY

Hy vọng điều này là hữu ích.


2
Liên kết đến một giải pháp tiềm năng luôn được hoan nghênh, nhưng vui lòng thêm ngữ cảnh xung quanh liên kết để những người dùng đồng nghiệp của bạn sẽ biết nó là gì và tại sao nó ở đó. Luôn trích dẫn phần có liên quan nhất của một liên kết quan trọng, trong trường hợp trang web mục tiêu không thể truy cập được hoặc vĩnh viễn ngoại tuyến. Hãy lưu ý rằng việc chỉ có nhiều hơn một liên kết đến một trang web bên ngoài là một lý do có thể là Tại sao và làm thế nào một số câu trả lời bị xóa? .
Machavity

4

Trước hết, hãy lưu ý rằng rất nhiều chi tiết về cách các luồng được triển khai và lên lịch là rất cụ thể đối với hệ điều hành. Nói chung, bạn không cần phải lo lắng về các luồng đang chờ nhau, vì hệ điều hành và phần cứng sẽ cố gắng sắp xếp để chúng chạy hiệu quả, cho dù là không đồng bộ trên hệ thống một bộ xử lý hay song song trên nhiều bộ xử lý.

Khi một luồng đã hoàn tất việc chờ đợi một thứ gì đó, hãy nói I / O, nó có thể được coi là có thể chạy được. Các luồng có thể chạy được sẽ sớm được lên lịch thực thi vào một thời điểm nào đó. Cho dù điều này được thực hiện như một hàng đợi đơn giản hay một cái gì đó phức tạp hơn, một lần nữa, hệ điều hành và phần cứng cụ thể. Bạn có thể coi tập hợp các chủ đề bị chặn như một tập hợp hơn là một hàng đợi được sắp xếp nghiêm ngặt.

Lưu ý rằng trên hệ thống một bộ xử lý, các chương trình không đồng bộ như được định nghĩa ở đây tương đương với các chương trình phân luồng.


0

I / O không đồng bộ có nghĩa là đã có một luồng trong trình điều khiển thực hiện công việc, vì vậy bạn đang sao chép chức năng và phải chịu một số chi phí. Mặt khác, thường không được ghi lại cách chính xác của chuỗi trình điều khiển hoạt động và trong các tình huống phức tạp, khi bạn muốn kiểm soát hành vi hết thời gian / hủy / bắt đầu / dừng, đồng bộ hóa với các luồng khác, bạn nên thực hiện chuỗi của riêng bạn. Đôi khi nó cũng dễ dàng hơn để lập luận bằng các thuật ngữ đồng bộ.


5
Đó không phải là cách hoạt động của I / O không đồng bộ. Về cơ bản, I / O là theo hướng sự kiện (bạn khởi tạo I / O tới một thiết bị, sau đó, thiết bị sẽ hoàn thành nó và hy vọng sẽ cho bạn biết điều đó bằng một ngắt). Có một số loại I / O (như I / O đĩa) trong đó trình điều khiển sử dụng một luồng nhân vì lý do hơi khó hiểu; nhưng đối với mạng, nó hoạt động không đồng bộ hoàn toàn.
Glyph

0

xem http://en.wikipedia.org/wiki/Thread_(computing)#I.2FO_and_scheduling

Tuy nhiên, việc sử dụng chặn các cuộc gọi hệ thống trong luồng người dùng (trái ngược với luồng nhân) hoặc sợi có thể có vấn đề. Nếu một luồng người dùng hoặc một sợi thực hiện lệnh gọi hệ thống bị chặn, các luồng và sợi người dùng khác trong quá trình này sẽ không thể chạy cho đến khi lệnh gọi hệ thống trả về. Ví dụ điển hình của vấn đề này là khi thực hiện I / O: hầu hết các chương trình được viết để thực hiện I / O một cách đồng bộ. Khi một thao tác I / O được bắt đầu, một lệnh gọi hệ thống sẽ được thực hiện và sẽ không quay trở lại cho đến khi hoàn tất thao tác I / O. Trong khoảng thời gian xen kẽ, toàn bộ tiến trình bị "chặn" bởi hạt nhân và không thể chạy, điều này khiến các luồng và sợi người dùng khác trong cùng một tiến trình không thể thực thi.

Theo đó, toàn bộ quá trình của bạn có thể bị chặn và không có chuỗi nào được lên lịch khi một chuỗi bị chặn trong IO. Tôi nghĩ rằng điều này là dành riêng cho hệ điều hành, và sẽ không phải lúc nào cũng được giữ.

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.