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

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

  • автор:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

См. также

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

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

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

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

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

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

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

См. также

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

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

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

Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see: https://aka.ms/ContentUserFeedback.

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

Работа с потоками

Теперь, когда известно, как создавать новые потоки выполнения программно с помощью типов из пространства имен System.Threading, давайте проясним разницу между потоками переднего плана и фоновыми потоками.

  • обеспечивают предохранение текущего приложения от завершения. Среда CLR не остановит приложение (что означает выгрузку текущего домена приложения) до тех пор, пока не будут завершены все потоки переднего плана.
  • воспринимаются средой CLR как расширяемые пути выполнения, которые в любой момент времени могут игнорироваться (даже если они в текущее время заняты выполнением некоторой части работы). Таким образом, если все потоки переднего плана прекращаются, то все фоновые потоки автоматически уничтожаются при выгрузке домена приложения.

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

Чтобы создать фоновый поток необходимо установить свойство IsBackground в true.

Приоритеты потоков

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

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

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

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

В классе Thread базовый приоритет потока устанавливается в свойстве Priority. Допустимые значения определены в перечислении ThreadPriority. Эти значения представляют различные уровни приоритета и выглядят следующим образом: Highest, AboveNormal, Normal, BelowNormal и Lowest.

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

Управление потоками

Поток создается за счет вызова метода Start() объекта Thread. Однако после вызова метода Start() новый поток все еще пребывает не в состоянии Running, а в состоянии Unstarted. В состояние Running поток переходит сразу после того, как планировщик потоков операционной системы выберет его для выполнения. Информация о текущем состоянии потока доступна через свойство Thread.ThreadState.

С помощью метода Thread.Sleep() поток можно перевести в состояние WaitSleepJoin и при этом указать, через какой промежуток времени поток должен возобновить работу.

Чтобы остановить поток, необходимо вызвать метод Thread.Abort(). При вызове этого метода в соответствующем потоке генерируется исключение типа ThreadAbortException. В случае если для этого исключения предусмотрен обработчик, перед завершением поток сможет выполнить необходимые операции по очистке. Чтобы продолжить выполнение потока после выдачи исключения ThreadAbortException, следует вызвать метод Thread.ResetAbort(). Состояние потока, получающего запрос на немедленное прекращение, изменяется с AbortRequested на Aborted, если поток не производит сброс.

Если необходимо дожидаться завершения работы потока, можно вызвать метод Thread.Join(). Этот метод блокирует текущий поток и переводит его в состояние WaitSleepJoin до тех пор, пока не будет завершен присоединенный к нему поток.

Потоки

Система ввода/вывода С предназначена для работы со множеством устройств, включая терминалы дисковые накопители и так далее. Хотя каждое устройство отличается от другого, система вводу вывода преобразует их в единое логическое устройство — поток. Все потоки похожи своим поведением. Поскольку потоки не зависят от устройств, одни и те же функции могут записывать информацию в файл на диске и использоваться для записи на другое устройство, например консоль. Существует два типа потоков: текстовые и двоичные.

Текстовые потоки

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

Двоичные потоки

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

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

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