Можете ли вы объяснить концепцию потоков? - PullRequest
175 голосов
/ 03 февраля 2009

Я понимаю, что поток является представлением последовательности байтов. Каждый поток предоставляет средства для чтения и записи байтов в заданное хранилище. Но какой смысл в потоке? Почему сам бэк-магазин не является тем, с чем мы взаимодействуем?

По какой-то причине эта концепция просто не подходит для меня. Я прочитал кучу статей, но думаю, что мне нужна аналогия или что-то в этом роде.

Ответы [ 15 ]

224 голосов
/ 03 февраля 2009

Слово «поток» было выбрано потому, что оно представляет (в реальной жизни) значение, очень похожее на то, что мы хотим передать, когда используем его.

Давайте немного забудем о бэк-магазине и начнем думать об аналогии с водным потоком. Вы получаете непрерывный поток данных, точно так же, как вода непрерывно течет в реке. Вы не обязательно знаете, откуда поступают данные, и чаще всего вам это не нужно; будь то из файла, сокета или любого другого источника, это не имеет (не должно) никакого значения. Это очень похоже на получение потока воды, при котором вам не нужно знать, откуда он исходит; будь то озеро, фонтан или другой источник, это не имеет (не должно) большого значения.

Тем не менее, как только вы начинаете думать, что вам нужны только те данные, которые вам нужны, независимо от того, откуда они берутся, абстракции, о которых говорили другие, становятся более ясными. Вы начинаете думать, что можете обернуть потоки, и ваши методы все равно будут работать идеально. Например, вы можете сделать это:

int ReadInt(StreamReader reader) { return Int32.Parse(reader.ReadLine()); }

// in another method:
Stream fileStream = new FileStream("My Data.dat");
Stream zipStream = new ZipDecompressorStream(fileStream);
Stream decryptedStream = new DecryptionStream(zipStream);
StreamReader reader = new StreamReader(decryptedStream);

int x = ReadInt(reader);

Как видите, становится очень легко изменить источник входного сигнала без изменения логики обработки. Например, чтобы прочитать данные из сетевого сокета вместо файла:

Stream stream = new NetworkStream(mySocket);
StreamReader reader = new StreamReader(stream);
int x = ReadInt(reader);

Так легко, как только может быть. И красота продолжается, так как вы можете использовать любой источник ввода, если вы можете создать для него потоковую «обертку». Вы могли бы даже сделать это:

public class RandomNumbersStreamReader : StreamReader {
    private Random random = new Random();

    public String ReadLine() { return random.Next().ToString(); }
}

// and to call it:
int x = ReadInt(new RandomNumbersStreamReader());

См? Пока ваш метод не заботится о том, что является источником ввода, вы можете настроить его различными способами. Абстракция позволяет очень элегантно отделить входные данные от логики обработки.

Обратите внимание, что созданный нами поток не имеет резервного хранилища, но он по-прежнему отлично подходит для наших целей.

Итак, подведем итог: поток - это просто источник ввода, скрывающий (абстрагирующий) другой источник. Пока вы не нарушите абстракцию, ваш код будет очень гибким.

37 голосов
/ 03 февраля 2009

Дело в том, что вам не нужно знать, что такое резервное хранилище - это абстракция над ним. На самом деле, даже не может быть хранилища резервных копий - вы можете читать из сети, и данные никогда не будут «храниться» вообще.

Если вы можете написать код, который работает независимо от того, говорите ли вы с файловой системой, памятью, сетью или чем-то еще, поддерживающим идею потока, ваш код будет гораздо более гибким.

Кроме того, потоки часто объединяются в цепочки - у вас может быть поток, который сжимает все, что в него помещено, записывает сжатую форму в другой поток или тот, который шифрует данные и т. Д. быть обратной цепью, расшифровывать, распаковывать или что-то еще.

30 голосов
/ 03 февраля 2009

Суть потока - обеспечить уровень абстракции между вами и резервным хранилищем. Таким образом, для данного блока кода, который использует поток, не нужно заботиться о том, является ли резервное хранилище дисковым файлом, памятью и т. Д. *

11 голосов
/ 03 февраля 2009

Дело не в ручьях, а в плавании. Если вы можете плыть одним потоком, то вы можете плыть любым потоком, с которым сталкиваетесь.

7 голосов
/ 03 февраля 2009

Чтобы добавить в эхо-камеру, поток - это абстракция, поэтому вам нет дела до основного хранилища. Это имеет смысл при рассмотрении сценариев с потоками и без них.

Файлы по большей части неинтересны, потому что потоки не делают ничего сверх того, что делали не потоковые методы, с которыми я знаком. Давайте начнем с интернет-файлов.

Если я хочу загрузить файл из Интернета, мне нужно открыть сокет TCP, установить соединение и получать байты, пока байтов больше не будет. Я должен управлять буфером, знать размер ожидаемого файла и писать код, чтобы определить, когда соединение разорвано, и обработать это соответствующим образом.

Допустим, у меня есть какой-то объект TcpDataStream. Я создаю его с соответствующей информацией о соединении, затем читаю байты из потока, пока не появится сообщение, что байтов больше нет. Поток обрабатывает управление буфером, условия окончания данных и управление соединением.

Таким образом, потоки облегчают ввод / вывод. Конечно, вы могли бы написать класс TcpFileDownloader, который делает то же, что и поток, но тогда у вас есть класс, специфичный для TCP. Большинство потоковых интерфейсов просто предоставляют методы Read () и Write (), а любые более сложные концепции обрабатываются внутренней реализацией. По этой причине вы можете использовать один и тот же базовый код для чтения или записи в память, файлы на диске, сокеты и многие другие хранилища данных.

4 голосов
/ 24 января 2016

Когда я впервые услышал о потоковой передаче, это было в контексте прямой трансляции с веб-камерой. Итак, один хост транслирует видео контент, а другой хост получает видео контент. Так это потоковое? Ну ... да ... но прямой эфир - это конкретная концепция, и я думаю, что этот вопрос относится к абстрактной концепции потоковой передачи. Смотри https://en.wikipedia.org/wiki/Live_streaming

Итак, давайте двигаться дальше.


Видео - не единственный ресурс, который можно транслировать. Звук можно транслировать на. Итак, мы сейчас говорим о потоковом медиа. См. https://en.wikipedia.org/wiki/Streaming_media. Теперь давайте сравним некоторые методы доставки данных друг с другом.

Загрузка классического файла не происходит в режиме реального времени. Прежде чем приступить к использованию файла, вам придется подождать, пока загрузка не будет завершена.

Прогрессивная загрузка позволяет просматривать видеофайл во время загрузки. Возможна перемотка вперед и назад. Для этого он использует буфер, который временно хранит данные в памяти компьютера, получающего видеофайл. Несмотря на то, что данные фрагментированы, они не являются потоковыми.

Streaming Происходит в режиме реального времени и порции данных. Потоковая передача реализована в прямом эфире. Клиенты, слушающие трансляцию, не могут перематывать вперед или назад. В видеопотоках данные отбрасываются после воспроизведения.

Потоковый сервер поддерживает двустороннее соединение со своим клиентом, а веб-сервер закрывает соединение после ответа сервера.


Аудио и видео - не единственное, что можно транслировать. Давайте посмотрим на концепцию потоков в руководстве по PHP.

поток - это ресурсный объект, который демонстрирует поведение в потоке. Тот может быть считано из или записано в линейным образом, и может быть возможность fseek () к произвольному месту в потоке.

В PHP ресурс - это ссылка на внешний источник, такой как файл, соединение с базой данных. Другими словами, поток - это источник, который можно прочитать или записать. Итак, если вы работали с fopen(), то вы уже работали с потоками.

Текст, аудио, zip файлы также могут быть переданы в потоковом режиме. Кроме того, потоковое вещание не ограничивается файлами. HTTP, FTP, SSH соединения и ввод / вывод также могут быть потоковыми.


Что википедия говорит о концепции потоковой передачи?

В информатике поток - это последовательность элементов данных доступно со временем. Поток можно рассматривать как предметы на конвейере лента обрабатывается по одному, а не большими партиями.

См .: https://en.wikipedia.org/wiki/Stream_%28computing%29.

Википедия ссылается на это: https://srfi.schemers.org/srfi-41/srfi-41.html и у авторов есть это, чтобы сказать о потоках:

Потоки, иногда называемые ленивыми списками, представляют собой последовательную структуру данных содержащие элементы, рассчитанные только по запросу. Поток либо нулевой или является парой с потоком в его cdr. Поскольку элементы потока являются вычисляется только при обращении, потоки могут быть бесконечными.

Таким образом, Stream на самом деле является структурой данных.


Мой вывод: поток - это источник, который может содержать данные, из которых можно читать или записывать последовательным способом. Поток не читает сразу все, что содержит источник, он читает / записывает последовательно.


Полезные ссылки:

  1. http://www.slideshare.net/auroraeosrose/writing-and-using-php-streams-and-sockets-zendcon-2011 Обеспечивает очень четкое представление
  2. https://www.sk89q.com/2010/04/introduction-to-php-streams/
  3. http://www.netlingo.com/word/stream-or-streaming.php
  4. http://www.brainbell.com/tutorials/php/Using_PHP_Streams.htm
  5. http://www.sitepoint.com/php-streaming-output-buffering-explained/
  6. http://php.net/manual/en/wrappers.php
  7. http://php.net/manual/en/intro.stream.php
  8. http://www.digidata -lb.com / потоковое / Streaming_Proposal.pdf
  9. http://www.webopedia.com/TERM/S/streaming.html
  10. https://en.wikipedia.org/wiki/Stream_%28computing%29
  11. https://srfi.schemers.org/srfi-41/srfi-41.html
4 голосов
/ 03 февраля 2009

Визуализация, которую я использую, - это конвейерные ленты, не на реальных фабриках, потому что я ничего об этом не знаю, а на мультипликационных фабриках, где предметы движутся по линиям и получают штампы, коробки, подсчитывают и проверяют с помощью последовательности глупых устройств.

У вас есть простые компоненты, которые делают одно, например, устройство для нанесения вишни на торт. Это устройство имеет входной поток тортов без вишни и выходной поток тортов с вишней. Есть три преимущества, о которых стоит упомянуть, структурируя вашу обработку таким образом.

Во-первых, это упрощает сами компоненты: если вы хотите положить шоколадную глазурь на торт, вам не нужно сложное устройство, которое знает все о пирогах, вы можете создать тупое устройство, которое прикрепляет шоколадную глазурь ко всему, что подается в это (в мультфильмах это заходит так далеко, что мы не знаем, что следующий предмет не торт, это Уайл Э. Койот).

Во-вторых, вы можете создавать разные продукты, помещая устройства в разные последовательности: возможно, вы хотите, чтобы ваши пирожные имели глазурь поверх вишни вместо вишни поверх глазури, и вы можете сделать это, просто меняя устройства вокруг на линии.

В-третьих, устройствам не нужно управлять инвентарем, упаковкой или распаковкой. Самый эффективный способ агрегирования и упаковки вещей может быть изменен: возможно, сегодня вы складываете свои пирожные в коробки по 48 штук и отправляете их на грузовике, но завтра вы захотите разослать коробки по шесть в ответ на индивидуальные заказы. Такое изменение может быть осуществлено путем замены или перенастройки машин в начале и в конце производственной линии; Вишневый автомат в середине строки не нужно менять, чтобы обрабатывать разное количество элементов за раз, он всегда работает с одним элементом за раз, и ему не нужно знать, как его ввод или вывод будучи сгруппированным.

4 голосов
/ 03 февраля 2009

Это просто концепция, еще один уровень абстракции, который делает вашу жизнь проще. И все они имеют общий интерфейс, что означает, что вы можете комбинировать их как в трубе. Например, закодировать в base64, затем сжать, а затем записать это на диск и все в одну строку!

3 голосов
/ 03 февраля 2009

Лучшее объяснение потоков, которые я видел, это глава 3 SICP . (Возможно, вам придется прочитать первые 2 главы, чтобы это имело смысл, но в любом случае вам следует: -)

Они вообще не используют стерамы для байтов, а целые числа. Большие моменты, которые я получил от этого, были:

  • Потоки списков с задержкой
  • Затраты на вычислительные ресурсы [в некоторых случаях нетерпеливого вычисления всего заранее) просто возмутительны
  • Мы можем использовать потоки для представления бесконечно длинных последовательностей
2 голосов
/ 01 сентября 2016

Другой момент (для чтения ситуации с файлом):

  1. stream может позволить вам сделать что-то еще до finished reading all content of the file.
  2. вы можете сэкономить память, так как не нужно загружать все содержимое файла сразу.
...