Многопоточность
Материал из Википедии — свободной энциклопедии
Многопото́чность — свойство операционной системы, заключающееся в том, что задача может выполняться в более чем 1 потоке, за счёт чего достигается более эффективное использование ресурсов вычислительной машины. Как правило, операционные системы, реализующие многозадачность, реализуют и многопоточность.
Сутью многопоточности является квазимногозадачность на уровне одного исполняемого процесса, т.е. все потоки выполняются в адресном пространстве процесса. На момент выполнения процесса он имеет как минимум один (главный) поток.
К достоинствам многопоточности в программировании можно отнести следующее:
- Упрощение программы в некоторых случаях, за счет использования общего адресного пространства.
- Меньшие относительно процесса временные затраты на создание потока.
- Повышение производительности процесса за счет распараллелизации процессорных вычислений и операций ввода/вывода.
[править] Типы реализации потоков
- Поток в пространстве пользователя. Каждый процесс имеет таблицу потоков, аналогичную таблице процессов ядра.
Достоинства и недостатки этого типа следующие:
Достоинства
- возможность реализации на ядре не поддерживающем многопоточность
- Более быстрое переключение, создание и завершение потоков
- процесс может иметь собственный алгоритм планирования.
Недостатки
- Отсутствие прерывания по таймеру внутри одного процесса
- При использовании блокирующего системного запроса все остальные потоки блокируются.
- Сложность реализации
- Поток в пространстве ядра. Наряду с таблицей процессов в пространстве ядра имеется таблица потоков.
- Смешанная реализация. Потоки работают в режиме пользователя, но при системных вызовах переключаются в режим ядра. Переключение в режим ядра и обратно является ресурсоемкой операцией и отрицательно сказывается на производительности системы. Поэтому было введено понятие волокна - облегченного потока, выполняемого исключительно в режиме пользователя. У каждого потока может быть несколько волокон. Подобный тип многопоточности реализован в ОС Windows.
[править] Взаимодействие потоков
В многопоточной среде часто возникают проблемы, связанные с использованием параллельно исполняемыми потоками одних и тех же данных или устройств. Для решения подобных проблем используются такие методы взаимодействия потоков, как взаимоисключения (мьютексы), семафоры, критические секции и события
- Взаимоисключения (mutex, мьютекс) - это объект синхронизации, который устанавливается в особое сигнальное состояние, когда не занят каким-либо потоком. Только один поток владеет этим объектом в любой момент времени, отсюда и название таких объектов - одновременный доступ к общему ресурсу исключается. После всех необходимых действий мьютекс освобождается, предоставляя другим потокам доступ к общему ресурсу.
- Семафоры представляют собой доступные ресурсы, которые могут быть приобретены несколькими потоками в одно и то же время, пока пул ресурсов не опустеет. Тогда дополнительные потоки должны ждать, пока требуемое количечтво ресурсов не будет снова доступно. Семафоры очень эффективны, поскольку они позволяют одновременный доступ к ресурсам.
- Критические секции обеспечивают синхронизацию подобно мьютексам за исключением того, что объекты, представляющие критические секции, доступны в пределах одного процесса. События, мьютексы и семафоры также можно использовать в однопроцессном приложении, однако критические секции обеспечивают более быстрый и более эффективный механизм взаимно-исключающей синхронизации. Подобно мьютексам объект, представляющий критическую секцию, может использоваться только одним потоком в данный момент времени, что делает их крайне полезными при разграничении доступа к общим ресурсам.
- События. События полезны в тех случаях, когда необходимо послать сообщение потоку, сообщающее, что произошло определенное событие. Например, при асинхронных операциях ввода и вывода из одного устройства, система устанавливает событие в сигнальное состояние когда заканчивается какая-либо из этих операций. Один поток может использовать несколько различных событий в нескольких перекрывающихся операциях, а затем ожидать прихода сигнала от любого из них.