Как стать автором
Обновить

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

Параллелизм и параллелизм

В многопоточном процессе на одном процессоре процессор может переключать исполнительные ресурсы между потоками, что приводит к одновременному выполнению.

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

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

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

Взгляд на многопоточную структуру

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

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

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

Интерфейс для поддержки многопоточности осуществляется через библиотеку подпрограмм, libpthread для потоков POSIX и libthread для потоков Solaris. Многопоточность обеспечивает гибкость за счет разделения ресурсов уровня ядра и уровня пользователя.

Потоки на уровне пользователя

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

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

  • Идентификатор потока

  • Состояние регистрации (включая ПК и указатель стека)

  • Стек

  • Сигнальная маска

  • Приоритет

  • Потоковое частное хранилище

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

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

Подводя итог, можно сказать, что потоки на уровне пользователя:

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

  • Быстрая синхронизация, поскольку синхронизация выполняется на уровне приложения, а не на уровне ядра.

  • Легко управляется библиотекой потоков; либо libpthread, либо libthread.

Легкие процессы

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

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


Примечание -

LWP в операционных средах Solaris 2, Solaris 7 и Solaris 8 — это не то же самое, что LWP в библиотеке SunOSTM 4.0 LWP, которые не поддерживаются в операционных средах Solaris 2, Solaris 7 и Solaris 8.


Подобно процедурам библиотеки stdio, таким как и функции, интерфейс потоков использует интерфейс LWP, и по многим из тех же причин. fopen()fread()open()read()

Облегченные процессы (LWP) соединяют уровень пользователя и уровень ядра. Каждый процесс содержит один или несколько LWP, каждый из которых запускает один или несколько пользовательских потоков. (См. рисунок 1-1.) Создание потока обычно включает в себя только создание некоторого пользовательского контекста, но не создание LWP.

Рисунок 1-1 Потоки пользовательского уровня и облегченные процессы

Graphic
Graphic

Каждый LWP является ресурсом ядра в пуле ядра и выделяется (присоединяется) и освобождается (отсоединен) для потока на основе каждого потока. Это происходит по мере планирования или создания и уничтожения потоков.

Планирование

POSIX определяет три политики планирования: политику первого входа (SCHED_FIFO), циклического перебора (SCHED_RR) и пользовательскую (SCHED_OTHER). SCHED_FIFO — это планировщик на основе очередей с различными очередями для каждого уровня приоритета. SCHED_RR похож на FIFO, за исключением того, что каждый поток имеет квоту времени выполнения.

И SCHED_FIFO, и SCHED_RR являются расширениями POSIX Realtime. SCHED_OTHER — это политика планирования по умолчанию.

Дополнительные сведения о политике SCHED_OTHER и эмуляции некоторых свойств политик SCHED_FIFO и SCHED_RR POSIX см. в разделе "LWP и классы планирования".

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

Область процесса (несвязанные потоки)

Несвязанные потоки создаются PTHREAD_SCOPE_PROCESS. Эти потоки запланированы в пользовательском пространстве для присоединения и отсоединения от доступных LWPp в пуле LWP. LWP доступны только потокам в этом процессе; то есть потоки запланированы на этих LWP.

В большинстве случаев нити должны быть PTHREAD_SCOPE_PROCESS. Это позволяет потокам перемещаться между LWP, что повышает производительность потоков (и эквивалентно созданию потока Solaris в THR_UNBOUND состоянии). Библиотека потоков решает, в отношении других потоков, какие потоки обслуживаются ядром.

Область действия системы (связанные потоки)

Связанные потоки создаются PTHREAD_SCOPE_SYSTEM. Boundthread постоянно присоединяется к LWP.

Каждый связанный поток привязан к LWP на время существования потока. Это эквивалентно созданию потока Solaris в THR_BOUND состоянии. Вы можете привязать поток, чтобы дать ему альтернативный стек сигналов или использовать специальные атрибуты планирования с планированием в реальном времени. Все планирование выполняется операционной средой.


Примечание -

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


Отмена

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

Функция отмены pthreads позволяет асинхронное или отложенное завершение потока. Асинхронная отмена может произойти в любое время; отсроченная отмена может произойти только в определенных точках. Отложенная отмена является типом по умолчанию.

Синхронизация

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

Четыре модели синхронизации — это блокировки мьютекса, блокировки чтения и записи, переменные условий и семафоры.

  • Блокировки Mutex позволяют только одному потоку одновременно выполнять определенный участок кода или получать доступ к определенным данным.

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

  • Переменные условия блокируют потоки до тех пор, пока определенное условие не будет выполнено.

  • Подсчет семафоров обычно координирует доступ к ресурсам. Счетчик — это ограничение на количество потоков, имеющих доступ к семафору. Когда счетчик достигнут, семафор блокируется.

Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.