Мьютекс, семафор, критические секции
Синхронизация объектов: мьютекс, семафор, критические секции
Критические секции обеспечивают синхронизацию подобно мьютексам (о мьютексах см. далее) за исключением того, что объекты, представляющие критические секции, доступны в пределах одного процесса. События, мьютексы и семафоры также можно использовать в "однопроцессном" приложении, однако критические секции обеспечивают более быстрый и более эффективный механизм взаимно-исключающей синхронизации. Подобно мьютексам объект, представляющий критическую секцию, может использоваться только одним потоком в данный момент времени, что делает их крайне полезными при разграничении доступа к общим ресурсам. Трудно предположить что-нибудь о порядке, в котором потоки будут получать доступ к ресурсу, можно сказать лишь, что система будет "справедлива" ко всем потокам.
Мьютекс (взаимоисключение, mutex) - это объект синхронизации, который устанавливается в особое сигнальное состояние, когда не занят каким-либо потоком. Только один поток владеет этим объектом в любой момент времени, отсюда и название таких объектов - одновременный доступ к общему ресурсу исключается. Например, чтобы исключить запись двух потоков в общий участок памяти в одно и то же время, каждый поток ожидает, когда освободится мьютекс, становится его владельцем и только потом пишет что-либо в этот участок памяти. После всех необходимых действий мьютекс освобождается, предоставляя другим потокам доступ к общему ресурсу.
Два (или более) процесса могут создать мьютекс с одним и тем же именем, вызвав метод CreateMutex . Первый процесс действительно создает мьютекс, а следующие процессы получают хэндл уже существующего объекта. Это дает возможность нескольким процессам получить хэндл одного и того же мьютекса, освобождая программиста от необходимости заботиться о том, кто в действительности создает мьютекс. Если используется такой подход, желательно установить флаг bInitialOwner в FALSE, иначе возникнут определенные трудности при определении действительного создателя мьютекса.
Несколько процессов могут получить хэндл одного и того же мьютекса, что делает возможным взаимодействие между процессами. Вы можете использовать следующие механизмы такого подхода:
"22. Магнитные усилители без обратной связи" - тут тоже много полезного для Вас.
Дочерний процесс, созданный при помощи функции CreateProcess может наследовать хэндл мьютекса в случае, если при его (мьютекса) создании функией CreateMutex был указан параметр lpMutexAttributes .
Процесс может получить дубликат существующего мьютекса с помощью функции DuplicateHandle .
Процесс может указать имя существующего мьютекса при вызове функций OpenMutex или CreateMutex .
Вообще говоря, если вы синхронизируете потоки одного процесса, более эффективным подходом является использование критических секций.
Семафоры - хорошо понимаемая концепция в компьютерной науке. По своей сути, семафор это одно целое значение в сочетании с парой функций, которые обычно называются P и V. Процесс, желающий войти в критическую секцию, вызовет P на соответствующем семафоре; если в семафоре значение больше нуля, это значение уменьшается на единицу и этот процесс продолжается. Если, наоборот, в семафоре значение равно 0 (или меньше), процесс должен ждать, пока кто-нибудь другой освободит семафор. Разблокирование семафора осуществляется вызовом V; эта функция увеличивает значение семафора и, если необходимо, будит ожидающие процессы. Когда семафоры используются для взаимного исключения, предохраняя множество процессов от одновременного выполнения в критической секции, их значение будет проинициализировано в 1. Такой семафор в любой данный момент времени может удерживаться только одним процессом или потоком. Семафор, используемый в этом режиме, иногда называют мьютекс (флаг), что, конечно же, расшифровывается как "взаимное исключение" (mutex, mutual exclusion). Почти все семафоры, найденные в ядре Linux, используются для взаимного исключения. |