Выполнение синхронизации нескольких потоков
Чтобы избежать состязания исполнения и взаимоблокировок, необходимо синхронизировать доступ многочисленных потоков к совместно используемым ресурсам. Синхронизация также необходима и для того, чтобы гарантировать, что взаимозависимый код исполнится в полном соответствии с порядком следования.
Имеется
ряд объектов, дескрипторы которых могут быть использованы, чтобы синхронизировать многопоточную работу. Эти объекты включают в себя:Состояние каждого из этих объектов является, или сигнальным, или не сигнальным. Когда Вы определяете дескриптор любого из этих объектов при вызове одной из
функций ожидания (wait functions), исполнение вызывающего потока блокируется до тех пор, пока состояние заданного объекта не становится сигнальным.Некоторые из этих объектов полезны при блокировании потока, пока не произойдет некоторое событие. Например, дескриптором буфера консольного ввода данных подается сигнал тогда, когда там не читается ввод данных, таких как щелчок кнопки мыши или нажатие клавиши. Дескрипторы процессов и потоков подают сигнал тогда, когда процесс или поток заканчивает свою работу. Это позволяет процессу, например, создавать дочерний процесс, и затем заблокировать свое собственное выполнение, до тех пор, пока новый процесс не закончит свою работу.
Другие объекты полезны при защите совместно используемых ресурсов от одновременного обращения к ним. Например, каждый из множества потоков может иметь дескриптор объекта мьютекс (флажка блокировки). Перед обращением к совместно используемому ресурсу, потоки должны вызвать одну из функций ожидания (
wait functions), чтобы дождаться сигнального состояния мьютекса. Когда мьютекс становится сигнальным то, только одному ожидающему потоку разрешается обратиться к ресурсу. Состояние мьютекса немедленно сбрасывается в не сигнальное, так что любые другие ожидающие потоки остаются заблокированными. Когда поток завершает работу с ресурсом, он должен переключить мьютекс в сигнальное состояние, чтобы дать возможность другим потокам обратиться к ресурсу.Для потоков единственного процесса, объекты критической секции программы обеспечивают более эффективное средство синхронизации, чем мьютексы. Критическая секция программы используется подобно мьютексу, чтобы включать один поток на время использования защищенного ресурса. Поток может использовать функцию
EnterCriticalSection, чтобы запросить монопольное использование критической секции программы. Если секция уже принадлежит другому потоку, поток, который её затребовал, блокируется. Поток может использовать функцию TryEnterCriticalSection, чтобы запросить монопольное использование критической секции программы, без блокировки после отказа на её получение. После того, как поток получает монопольное использование, он свободен в использовании защищенного ресурса. Выполнение других потоков процесса не затрагивается, если они не пытаются входить в ту же самую критическую секцию программы.Функция
WaitForInputIdle заставляет поток ждать до тех пор, пока заданный процесс не инициализируется и не дождется ввода данных от пользователя вне зависимости от вводимых данных. Вызов WaitForInputIdle может быть полезен для синхронизации родительских и дочерних процессов, потому что функция CreateProcess возвращает значение без ожидания завершения инициализации дочернего процесса.За дополнительной информацией обратитесь к главе
Синхронизация.