Что такое потоки и многопоточность

[C++] часть 1: многопоточность, конкурентность и параллелизм: ОСНОВЫ

Что такое потоки и многопоточность. Смотреть фото Что такое потоки и многопоточность. Смотреть картинку Что такое потоки и многопоточность. Картинка про Что такое потоки и многопоточность. Фото Что такое потоки и многопоточность

Простое руководство по изучению многопоточности, конкурентности и параллелизма в C++

Вначале, когда ещё только состоялось моё знакомство с многопоточностью в C++, многое было мне непонятным и сбивало с толку. Сложность программы расцветала буйным цветом (именно так: подобно прекрасному цветку), конкурентность и параллелизм с их недетерминированным поведением меня просто убивали, и всё было как в тумане. Так что мне легко понять всех приступающих к изучению этих понятий. Спешу избавить вас от мучений и предлагаю вашему вниманию это простое руководство по изучению конкурентности, параллелизма и многопоточности в C++ (в конце данной статьи расписан план, в соответствии с которым мы будем двигаться дальше).

А пока освежим в памяти основные понятия и попробуем на вкус код, выполняемый в многопоточной среде.

1. Что такое поток?

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

2. Что такое конкурентность/параллелизм

Что такое потоки и многопоточность. Смотреть фото Что такое потоки и многопоточность. Смотреть картинку Что такое потоки и многопоточность. Картинка про Что такое потоки и многопоточность. Фото Что такое потоки и многопоточность

3. Основные операции с потоками с помощью std::thread

Здесь вы можете найти пример кода, иллюстрирующий практически всё, что написано выше.

4. Зачем нужна синхронизация?

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

Что такое потоки и многопоточность. Смотреть фото Что такое потоки и многопоточность. Смотреть картинку Что такое потоки и многопоточность. Картинка про Что такое потоки и многопоточность. Фото Что такое потоки и многопоточность

Поток должен объявить, что он использует. А затем, прежде чем трогать этот объект, проверить, не использует ли его кто-то ещё. Зелёный поток смотрит ТВ? Значит, никто не должен трогать ТВ (другие могут рядышком сесть и посмотреть, если что). Это можно сделать с помощью мьютекса.

Пример кода

Обратимся к коду. Теперь вы сами можете проверить это недетерминированное поведение многопоточности.

В отличие от однопоточной реализации, каждое выполнение даёт разный и непредсказуемый результат (единственное, что можно сказать определённо: строки А и B упорядочены по возрастанию). Это может вызвать проблемы, когда очерёдность команд имеет значение.

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

Доступ должен быть синхронизирован.

Заключение

Вы можете сказать: «Батюшки! Сколько всего намешано в этой статье!» Просто помните, что не надо пытаться понять всё и сразу, важно ухватить основные идеи.

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

План статей

В будущих статьях будут освящены следующие темы:

Библиотека C++11 представляет стандартный механизм для синхронизации, независимый от базовой платформы, так что говорить о потоках, выполняемых в Linux и Windows, мы не будем. Тем более, что основные принципы похожи.

В следующей статье рассмотрим примитив синхронизации мьютекса и как его задействовать по максимуму.

Источник

Национальная библиотека им. Н. Э. Баумана
Bauman National Library

Персональные инструменты

Многопоточность

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

Содержание

Описание

Многопоточность (как доктрину программирования) не следует путать ни с многозадачностью, ни с многопроцессорностью, несмотря на то, что операционные системы, реализующие многозадачность, как правило, реализуют и многопоточность.

Достоинства
Недостатки

Аппаратная реализация

Различают две формы аппаратной реализации многопоточности:

Типы реализации потоков

Взаимодействие потоков

В многопоточной среде часто возникают проблемы, связанные с использованием параллельно исполняемыми потоками одних и тех же данных или устройств. Для решения подобных проблем используются такие методы взаимодействия потоков, как взаимоисключения (мьютексы), семафоры, критические секции и события. [Источник 2]

Особенности реализации

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

Еще одной областью исследований является то, какие типы событий должны вызывать переключение потоков: потери в кэш-памяти, межпотоковая связь, завершение DMA и т.д. [Источник 3]

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

Критика терминологии

Термин «поток» связан с переводами иностранной технической литературы, выполненными в 1970-х годах издательством «Мир». В настоящее время в «академических кругах» (то есть в учебниках, методических пособиях, курсах вузов, диссертациях и пр.) он считается эталонным. Это противоречит его же переводу «нить» в общеязыковом контексте, а также создаёт путаницу с термином Data stream.

Потоки называют также потоками выполнения (от англ. thread of execution); иногда называют «нитями» (буквальный перевод англ. thread) или неформально «тредами».

Источник

Основы многопоточности

Что такое потоки и многопоточность. Смотреть фото Что такое потоки и многопоточность. Смотреть картинку Что такое потоки и многопоточность. Картинка про Что такое потоки и многопоточность. Фото Что такое потоки и многопоточность

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

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

Компьютерный процесс в сравнении с потоком

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

Поток — это не что иное, как сегмент процесса. Потоки — исполняемые сущности, которые выполняют задачи, стоящие перед исполняемым приложением. Процесс завершается, когда все потоки заканчивают выполнение.

Роль ядер процессора

Каждый поток в процессе — это задача, которую должен выполнить процессор. Большинство процессоров сегодня умеют выполнять одновременно две задачи на одном ядре, создавая дополнительное виртуальное ядро. Это называется одновременная многопоточность или многопоточность Hyper-Threading, если речь о процессоре от Intel. Эти процессоры называются многоядерными процессорами. Таким образом, двухъядерный процессор имеет 4 ядра: два физических и два виртуальных. Каждое ядро может одновременно выполнять только один поток.

Почему многопоточность?

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

Время запачкать руки

Мы напишем программу, где запустим две функции (выполним две задачи). Сначала мы будем выполнять функции последовательно, через один и тот же поток, а затем создадим отдельные потоки для каждой из них. При этом отметим время выполнения для обоих подходов и увидим кое-что волшебное:

Summation1 и Summation2 — это два класса-заглушки, которые нам нужно выполнить. На их месте может быть любая бизнес-логика, которую вам захочется реализовать. Я только добавил случайные циклы, чтобы увеличить время выполнения — это поможет лучше продемонстрировать результаты:

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

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

На мой взгляд, понимание основ чего-то — лучший способ это “что-то” освоить. Надеюсь, эта статья помогла вам получить представление о необходимости и полезности многопоточного программирования.
Существует гораздо больше информации о потоках: жизненный цикл потоков, проблемы синхронности и способы их решения и т. д. Обязательно ознакомьтесь с ними. Как говорится, тяжело в учении — легко в бою!

Источник

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

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

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

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

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

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

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

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

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

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

Источник

Потоки (threads) и многопоточное выполнение программ (multi-threading)

Презентацию к данной лекции Вы можете скачать здесь.

Введение

Многопоточность (multi- threading ) – одна из наиболее интересных и актуальных тем в данном курсе и, по-видимому, в области ИТ вообще, и, кроме того, одна из излюбленных тем автора. Актуальность данной темы особенно велика, в связи с широким распространением многоядерных процессоров. В лекции рассмотрены следующие вопросы:

Однопоточные и многопоточные процессы

Что такое потоки и многопоточность. Смотреть фото Что такое потоки и многопоточность. Смотреть картинку Что такое потоки и многопоточность. Картинка про Что такое потоки и многопоточность. Фото Что такое потоки и многопоточность

Многопоточность имеет большие преимущества:

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

История многопоточности

Как небезынтересно отметить, один из первых шагов на пути к широкому использованию многопоточности, по-видимому, был сделан в 1970-е годы советскими разработчиками компьютерной аппаратуры и программистами. МВК «Эльбрус-1», разработанный в 1979 году, поддерживал в аппаратуре и операционной системе эффективную концепцию процесса, которая была близка к современному понятию облегченного процесса. В частности, процесс в «Эльбрусе» однозначно характеризовался своим стеком. Иначе говоря, все процессы были облегченными и исполнялись в общем пространстве виртуальной памяти – других процессов в «Эльбрусе» просто не было!

Далее, в середине 1990-х гг. была выпущена ОС Windows NT, в которую была также включена многопоточность.

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

Источник

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

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