Sự khác biệt giữa một luồng và một hàng đợi là gì?


13

Sự khác biệt giữa một luồng và một hàng đợi là gì? Cả hai đều có khái niệm về một tập hợp các phần tử, nhưng có xu hướng có các cách triển khai khác nhau và từ vựng khác nhau về 'insert' / 'extract' (stream) so với 'enqueue' / 'dequeue' (queue). Là những hoán đổi cho nhau? Họ có đề xuất các khái niệm hoặc mô hình khác nhau? Nếu vậy, sự khác biệt là gì?


Rõ ràng "dòng" đề cập đến những điều khác nhau trong các bối cảnh khác nhau. Có sự khác biệt về đặc điểm giữa một luồng ký tự so với giao diện Windows IStream trong COM so với luồng sự kiện trong kiến ​​trúc. Bạn có thể làm rõ?
rwong

Một người thợ rừng tập hợp một ít nước từ một con suối, nhưng họ không tiêu thụ hết nước. Vì vậy, có ý nghĩa thu thập một số tiền từ một luồng mà không hoàn toàn tiêu thụ nó. Mặt khác, các mục trong hàng đợi có thể bị cạn kiệt.
emallove

Câu trả lời:


11

Một dòng không phải là thực sự là một cấu trúc dữ liệu như vậy (theo lý thuyết), nhưng là một chuỗi các tín hiệu kỹ thuật số mạch lạc được mã hóa (các gói dữ liệu hoặc các gói dữ liệu) được sử dụng để truyền hoặc nhận thông tin". Vì vậy, về cơ bản là một chuỗi các dữ liệu.

Một hàng đợi là một cơ chế FIFO đơn giản cho phép bạn thêm các mục vào mặt sau của hàng đợi hoặc lấy từ phía trước.

Các luồng luôn có nguồn, ví dụ: tệp, vị trí mạng, v.v ... Hàng đợi vốn không chứa bất kỳ dữ liệu nào.

Vì vậy, về cơ bản chúng khá khác nhau về khái niệm và như Mason chỉ ra, chúng được sử dụng khác nhau.


Thực sự có một cấu trúc dữ liệu gọi là "luồng", với (một cách hiệu quả) một danh sách dữ liệu cần tiêu thụ, với chức năng nhà sản xuất ở phần đuôi của nó, có thể gọi được nếu bạn cần nhiều yếu tố hơn.
Vatine

Lệnh 'có' của Unix trông giống như một luồng nhưng không có nguồn dữ liệu cụ thể.
JBRWilkinson

@JBRWilkinson: Chạy mà không có đối số, nguồn dữ liệu cho yes(1)là chuỗi mặc định được nhúng. Chạy với một đối số, đó là bất cứ điều gì cung cấp đối số.
Blrfl

Vâng, bạn đã đúng - tất cả dữ liệu phải đến từ một nơi nào đó. Có lẽ điểm thực tế ở đây là một hàng đợi có thể trống và một luồng, theo định nghĩa, thường là không?
JBRWilkinson

2
@JBRWilkinson Không phải vậy. Trong sơ đồ, (stream)trả về một luồng trống. Ngoài ra, câu trả lời này là sai, một luồng là cấu trúc dữ liệu, các luồng có thể không có nguồn và các luồng không chứa bất kỳ dữ liệu nào, chúng có thể là không hoặc không hoặc danh sách trống. Xem SRFI-41 để biết thêm.
mẫu

5

Sự khác biệt cơ bản là ở cách chúng được sử dụng. Trong một luồng, bạn thường chỉ sử dụng một mặt của thao tác: bạn mở một luồng để đọc hoặc viết, nhưng không phải cả hai. Trong khi đó với một hàng đợi, bạn đang đặt các mặt hàng và lấy chúng ra.

Ngoài ra, hàng đợi rất nghiêm ngặt về thứ tự bạn đặt mọi thứ và tháo chúng ra, trong khi các luồng thường (nhưng không phải lúc nào cũng) hỗ trợ một Seekthao tác, đặc biệt nếu bạn đọc từ chúng.


3
FileStreamcó thể được mở trong ReadWritechế độ.
Robert Harvey

2
..và hàng đợi ưu tiên cung cấp các tùy chọn về thứ tự
Petter Nordlander

5

Theo kinh nghiệm của tôi, một luồng là một chuỗi các byte được tạo ra / tiêu thụ ở tốc độ thường được xác định bởi dữ liệu trong luồng. Ví dụ, một luồng dữ liệu MPEG sẽ có các tiêu đề khung mô tả chuỗi byte tiếp theo làm gì và số lượng cần phải tiêu thụ. Tuần tự hóa nhị phân của một tài liệu sẽ tương tự. Nó không phải lúc nào cũng tự mô tả: viết vào STDOUT có thể được thực hiện theo cách thông minh nhưng nó có thể là dữ liệu có thể đọc được / không phân tích được của con người.

Ngược lại, một hàng đợi thường là một loại đối tượng nổi tiếng (hoặc các đối tượng hỗ trợ giao diện) được tiêu thụ toàn bộ. Một ví dụ có thể là một hàng các công việc cơ sở dữ liệu được xử lý bởi một số công nhân cơ sở dữ liệu.


5

Sự khác biệt giữa luồng và hàng đợi là cách kiểm soát tốc độ dữ liệu:

  • trong một hàng đợi, người gửi thích nghi với tốc độ của người đọc. Người gửi quyết định phải làm gì nếu hàng đợi đầy: chờ đợi hàng có sẵn hoặc ném dữ liệu đi.

  • trong một luồng, người đọc thích nghi với tốc độ của người gửi, Người đọc quyết định phải làm gì nếu dữ liệu mới đến trước khi dữ liệu cũ được sử dụng.

Với viễn cảnh đó, các luồng ký tự như ống Unix sẽ không đủ điều kiện là luồng mà là hàng đợi.


Trong truyền phát video thích ứng, máy chủ sẽ điều chỉnh luồng trung thực thấp hơn vì máy khách không theo kịp.
JBRWilkinson

@JBRWilkinson - Trong truyền phát video thích ứng , máy chủ chỉ gửi nhiều biến thể của một luồng với tốc độ bit khác nhau. Đây vẫn là trách nhiệm của khách hàng trong số các luồng này.
mouviciel

Vâng, truyền phát HTTP làm điều đó. Tôi có nghĩa là cuộc gọi video là điểm-điểm và dữ liệu không được mã hóa trước. Xấu của tôi - tôi nên đã rõ ràng.
JBRWilkinson

Mục đích của một luồng ký tự là dữ liệu được tiêu thụ nhiều hơn hoặc ít hơn khi nó được tạo ra: đó là một luồng dữ liệu chứ không phải là một phương tiện để giữ nó. Chúng tôi biết rằng điều này không hoàn hảo trong thực tế, nhưng từ quan điểm ẩn dụ, điều đó được kỳ vọng là đúng: người đọc có thể xử lý luồng nhanh như khi nó đến.

5

Nếu chúng ta suy nghĩ trực quan hơn về cách các từ thường được sử dụng , chúng ta có thể tránh sự lộn xộn của việc sử dụng cụ thể theo các ngôn ngữ và cách triển khai cụ thể, để các thuật ngữ này thực sự có nghĩa là gì đó:

  • Một hàng người xếp hàng chờ đợi và được phục vụ từng người một. Nhiều người tham gia xếp hàng ở đuôi. Mọi người đều chờ đợi khi tiến hành dịch vụ và thời gian phục vụ dự kiến ​​sẽ thay đổi. Bạn có thể nói về tổng số người được phục vụ.
  • Một dòng người, ví dụ như rời khỏi một tòa nhà qua một cánh cửa, không được phục vụ từng người một, họ chỉ vượt qua điểm thoát với tốc độ ổn định ít nhiều. Sự chậm trễ không được mong đợi và không được dung nạp tốt. Bạn có thể nói về một tỷ lệ người: một người mỗi giây.

Đó là ý định của các điều khoản này. Họ là những ẩn dụ. (như mọi thứ khác) (Suỵt! bạn sẽ phá hỏng câu chuyện!)


2

Hàng đợi là một khái niệm cấp cao hơn một luồng. Các yếu tố cơ bản của hàng đợi là một thông điệp / đối tượng, là một cấu trúc dữ liệu mạch lạc (thường được gõ) có thể được người tiêu dùng tự hiểu. Mặt khác, tại cơ sở của một luồng , có các bit / byte / ký tự có kích thước cố định, thường là vô nghĩa đối với ứng dụng. Một chuỗi các ký tự này có thể soạn một "thông điệp", nhưng API luồng để lại cho ứng dụng để phân chia chuỗi các ký tự thành các đoạn hợp lý.

API Stream thường cũng cho phép đọc và ghi một phần, nếu bộ đệm luồng đầy và phía bên kia không đọc / ghi; các ứng dụng xử lý hàng đợi thường mong đợi hàng đợi xử lý các nội bộ này.

Một hàng đợi có thể được thực hiện trên đầu luồng, điều này được thực hiện bằng cách thực hiện đóng khung thư. Ví dụ: TCP cung cấp giao diện truyền phát, HTTP được xây dựng bên trên TCP và thêm khung hình thông báo bằng cách sử dụng mã hóa chuyển nội dung Độ dài / khối. Người dùng API kết nối HTTP được trừu tượng hóa từ việc xử lý phân tách luồng kết nối HTTP thành các yêu cầu HTTP.

Mặt khác, thông thường, sẽ ít có ý nghĩa hơn khi triển khai API luồng trên đầu hàng đợi, vì việc xử lý khung tin nhắn sẽ thêm chi phí không cần thiết.


Thật đáng để thêm API đó cho hàng đợi thường tạo / tiêu thụ một yếu tố duy nhất tại một thời điểm, trong khi API phát trực tuyến thường tạo / tiêu thụ nhiều "từ" cùng một lúc. Mặc dù tôi đồng ý, đặc điểm xác định là hàng đợi ở mức cao và có cấu trúc, trong khi luồng ở mức thấp và không có cấu trúc.
Alexey

0

Trong các ngôn ngữ lập trình chức năng (ví dụ Scala) và có thể các ngôn ngữ khác cũng vậy, các luồng thực sự giống như các danh sách chức năng và chúng là các hàng đợi. Tôi nên lưu ý, tuy nhiên, hàng đợi thực sự có thể được thực hiện bằng cách sử dụng một cặp danh sách . Trong Scala và có lẽ ở nơi khác, Stream chỉ là một Danh sách lười biếng - cụ thể hơn, phần đuôi của danh sách là a lazy val.

Các luồng chức năng có thể chia sẻ một số điểm tương đồng với các hàng đợi, trái ngược với các danh sách, theo đó bạn có thể sử dụng chúng theo cách mà bạn không giữ tham chiếu đến đầu luồng - nhưng bạn phải cẩn thận: https: // stackoverflow.com/a/5159356/3096687 . Điều này hơi giống với một cuộc gọi dequeue đến hàng đợi (mặc dù trong trường hợp của một luồng, bạn thực hiện điều đó một cách ngầm định: http://daily-scala.blogspot.com/2010/01/streams-2-stream-conevelop.html ).


-1

Luồng là một khái niệm / khung để sản xuất và sử dụng chuỗi dữ liệu vô hạn hoặc song song hoặc hàng loạt. Que là một cấu trúc dữ liệu thông qua đó luồng có thể được thực hiện. giống như danh sách hoặc seq thông qua đó luồng có thể được thực hiện.

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.