Что такое поток в с
Перейти к содержимому

Что такое поток в с

  • автор:

Потоки и работа с ними

Многопоточность позволяет увеличивать скорость реагирования приложения и, если приложение работает в многопроцессорной или многоядерной системе, его пропускную способность.

Процессы и потоки

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

По умолчанию программа .NET запускается с одним потоком, часто называемым основным потоком. Тем не менее она может создавать дополнительные потоки для выполнения кода параллельно или одновременно с основным потоком. Эти потоки часто называются рабочими потоками.

Цели применения нескольких потоков

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

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

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

Как использовать многопоточность в .NET

Начиная с .NET Framework 4, для многопоточности рекомендуется использовать библиотеку параллельных задач (TPL) и Parallel LINQ (PLINQ). Дополнительные сведения см. в разделе Параллельное программирование.

Библиотека параллельных задач и PLINQ полагаются на потоки ThreadPool. Класс System.Threading.ThreadPool предоставляет приложения .NET с пулом рабочих потоков. Также можно использовать потоки из пула потоков. Дополнительные сведения см. в разделе Управляемый пул потоков.

Наконец, можно использовать класс System.Threading.Thread, который представляет управляемый поток. Дополнительные сведения см. в разделе Использование потоков и работа с потоками.

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

Исключения следует обрабатывать в потоках. Необработанные исключения в потоках, как правило, приводят к завершению процесса. Дополнительные сведения см. в статье Исключения в управляемых потоках.

См. также

  • Объекты и функциональные возможности работы с потоками
  • Рекомендации по работе с потоками
  • Процессы и потоки
  • Параллельная обработка в .NET
  • Асинхронные шаблоны программирования в .NET

Совместная работа с нами на GitHub

Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.

Что такое поток (stream)?

В книжках пишут про стандартные потоки ввода-вывода в C++, запись в поток и чтение из потока. Что такое поток, и что он из себя представляет?

Отслеживать
31.2k 13 13 золотых знаков 98 98 серебряных знаков 159 159 бронзовых знаков
задан 14 июл 2015 в 15:29
357 1 1 золотой знак 2 2 серебряных знака 8 8 бронзовых знаков

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Поток это просто абстракция. Удобная абстракция для решения задач.

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

Рассмотрим например, такое чтение с консоли:

int n; std::string s; std::cin >> n >> s; 

и такие данные на вход:

123a aaa 

Как это будет работать? Вначале стандартному потоку нужно прочитать число. Он будет читать до тех пор, пока там число. В n попадет 123. В «трубе осталось «a aaa». Дальше нужно прочитать строку. А строка читается до пробела или перевода строки. Поэтому прочитается только одно a. А многие полагают, что прочитается три а. Я привел этот пример не просто так. На него многие попадаются.

Как это реализовано внутри? Очень просто. Есть очередь (то есть, если очень грубо — массив), откуда читают данные байт за байтом. Если в очереди ничего нет — библиотечный код обращается к функциям операционной системы и читает с консоли/файла/сокета) и складывает в очередь. Конечно, в некоторых случаях эта очередь может быть реализована на базе операционной системы, а может и явно. Но для пользователя (то есть программиста) это прозрачно.

Аналогично работает и вывод.

Чем удобны потоки?

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

Например, нужно сделать функцию форматированного вывода числа на консоль (со спец. пожеланиями). Можно конечно закодить вывод на std::cout, но как протестить? Можно написать функцию, которая будет на вход получать ostream (предок std::cout) и выводить в него. Потом можно использовать такую функцию и выводить в stringstream, который легко преобразовывается в строку и результат можно выверить тестом.

Что такое поток в с

Язык C# позволяет запускать и выполнять в рамках приложения несколько потоков, которые будут выполняться одновременно.

Для создания потока применяется один из конструкторов класса Thread :

  • Thread(ThreadStart) : в качестве параметра принимает объект делегата ThreadStart, который представляет выполняемое в потоке действие
  • Thread(ThreadStart, Int32) : в дополнение к делегату ThreadStart принимает числовое значение, которое устанавливает размер стека, выделяемого под данный поток
  • Thread(ParameterizedThreadStart) : в качестве параметра принимает объект делегата ParameterizedThreadStart, который представляет выполняемое в потоке действие
  • Thread(ParameterizedThreadStart, Int32) : вместе с делегатом ParameterizedThreadStart принимает числовое значение, которое устанавливает размер стека для данного потока

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

public delegate void ThreadStart();

То есть под этот делегат нам надо определить метод, который имеет тип void и не принимает никаких параметров. Примеры определения потоков:

Thread myThread1 = new Thread(Print); Thread myThread2 = new Thread(new ThreadStart(Print)); Thread myThread3 = new Thread(()=>Console.WriteLine("Hello Threads")); void Print() => Console.WriteLine("Hello Threads");

Для запуска нового потока применяется метод Start класса Thread:

using System.Threading; // создаем новый поток Thread myThread1 = new Thread(Print); Thread myThread2 = new Thread(new ThreadStart(Print)); Thread myThread3 = new Thread(()=>Console.WriteLine("Hello Threads")); myThread1.Start(); // запускаем поток myThread1 myThread2.Start(); // запускаем поток myThread2 myThread3.Start(); // запускаем поток myThread3 void Print() => Console.WriteLine("Hello Threads");

Преимуществом потоком является то, что они могут выполняться одновременно. Например:

using System.Threading; // создаем новый поток Thread myThread = new Thread(Print); // запускаем поток myThread myThread.Start(); // действия, выполняемые в главном потоке for (int i = 0; i < 5; i++) < Console.WriteLine($"Главный поток: "); Thread.Sleep(300); > // действия, выполняемые во втором потокке void Print() < for (int i = 0; i < 5; i++) < Console.WriteLine($"Второй поток: "); Thread.Sleep(400); > >

Здесь новый поток будет производить действия, определенные в методе Print, то есть выводить числа от 0 до 4 на консоль. Причем после каждого вывода производится задержка на 400 миллисекунд.

В главном потоке — в методе Main создаем и запускаем новый поток, в котором выполняется метод Print:

Thread myThread = new Thread(Print); myThread.Start();

Кроме того, в главном потоке производим аналогичные действия — выводим на консоль числа от 0 до 4 с задержкой в 300 миллисекунд.

Таким образом, в нашей программе будут работать одновременно главный поток, представленный методом Main, и второй поток, в котором выполняется метод Print. Как только все потоки отработают, программа завершит свое выполнение. В итоге мы получим следующий консольный вывод:

Главный поток: 0 Второй поток: 0 Главный поток: 1 Второй поток: 1 Главный поток: 2 Второй поток: 2 Главный поток: 3 Второй поток: 3 Главный поток: 4 Второй поток: 4

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

Что такое поток

Как и В, C++ не имеет встроенных возможностей ввода и вывода. Однако все компиляторы C++ объединяются с системным, объектно-ориентированным пакетом ввода-вывода, известным как iostream классы. Поток является центральным понятием iostream классов. Можно считать, что поток — это смарт-файл, который выступает в качестве источника и назначения для байт. Характеристики потока определяется его классом и пользовательскими операторами вставки и извлечения.

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

В этом разделе

См. также

Обратная связь

Были ли сведения на этой странице полезными?

Обратная связь

Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделе https://aka.ms/ContentUserFeedback.

Отправить и просмотреть отзыв по

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *