Приостановка потока (Sleep)

API

Sleep –
приостанавливает текущий поток на указанное число миллисекунд
SleepEx -
приостанавливает текущий поток на указанное число миллисекунд. Поток может быть возобновлен досрочно для завершения ввода/вывода.
RtSleepFt –
приостанавливает текущий поток на заданный в единицах 100 наносекунд интервал времени
RtSleepFtEx –
приостанавливает текущий поток на заданный в единицах 100 наносекунд интервал времени. Поток может быть возобновлен досрочно для завершения ввода/вывода.

Пример демонтрирует использование таймеров и приостановки потока.

Межпроцессное взаимодействие

В следующих разделах обсуждаются:

Имена объектов

Именованные объекты позволяют разным процессам иметь доступ к общим объектам. Максимальная длина имени, указанного при создании процесса, равна RTX_MAX_PATH символов и может включать любые символы за исключением обратной косой черты (\). Если процесс создал именованное событие, мьютекс, семафор или разделяемую память, другие объекты могут использовать это имя для вызова соответствующей функции (RtOpenEvent, RtOpenMutex, RtOpenSemaphore или RtOpenSharedMemory) для получения хэндла объекта. Имена объектов различают регистр символов.

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

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

Использование разделяемой памяти

RTSS-объект разделяемая память представляет собой область непэйджируемой (non-paged) физической памяти, которая может быть спроецирована на виртуальное адресное пространство процесса. Когда известно имя разделяемой памяти, другой процесс может спроецировать ее на свое адресное пространство. Для доступа к объекту разделяемая память надо знать его хэндл и виртуальный адрес. Для того, чтобы отсоединить процесс от разделяемой памяти, процесс должен закрыть хэндл объекта. Когда все процессы отсоединятся от объекта разделяемая память, произойдет следующее:

Обмен данными между процессами посредством Shared Memory

RTSS-объекты разделяемая память позволяет разделять блоки данных между несколькими процессами, включая RTSS и Win32 процессы. Для этого поток в каждом процессе должен иметь собственный уникальный для процесса хэндл RTSS-объекта разделяемая память и собственный уникальный для процесса указатель на адрес проекции разделяемой памяти на адресное пространство процесса. Эти хэндлы и адреса могут быть получены путем вызова функций RtCreateSharedMemory и RtOpenSharedMemory.

Использование RtCreateSharedMemory

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

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

Использование RtOpenSharedMemory

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

Объект разделяемая память всегда принадлежит RTSS подсистеме. Однако, Win32 процесс может создавать и открывать RTSS-объекты разделяемая память.

При создании объекта разделяемая память RTSS обеспечивает его блокированной памятью соответствующего размера.

Использование семафоров

RTSS-объект семафор является объектом синхронизации, который поддерживает счетчик, значение которого может находиться между нулем и определенным максимальным числом. Счетчик уменьшается на 1 каждый раз, когда функция ожидания объекта семафор (WaitForSingleObject) возвращает управление потоку. Счетчик увеличивается на переменное число при освобождении семафора. Когда счетчик достигает 0, семафор больше не считается свободным и ни один вызов WaitForSingleObject не может вернуть управление потоку, пока какой-либо поток не увеличит счетчик.

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

Т.к. несколько потоков могут влиять на счетчик, RTSS-семафором, в отличие от мьютекса, поток владеть не может. Это означает, что WaitForSingleObject, ожидающая семафор:

Однако, в отличие от Win32 семафоров, RTSS-семафоры поддерживают “приоритетное ожидание”. Это означает, что когда несколько потоков с различными приоритетами ожидают семафор, система гарантирует, что порядок, в котором потоки будут получать доступ к семафору, соответствует распределению приоритетов процессов в момент освобождения семафора.

Межпроцессное взаимодействие с использованием семафоров

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

Использование RtCreateSemaphore

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

Поток может определить, создал ли вызов RtCreateSemaphore новый семафор с помощью вызова функции GetLastError сразу после вызова RtCreateSemaphore. Если GetLastError вернет ERROR_ALREADY_EXISTS,, то новый семафор не был создан.

Использование RtOpenSemaphore

RtOpenSemaphore возвращает хэндл RTSS семафора. Параметр dwDesiredAccess может принимать значения SEMAPHORE_ALL_ACCESS и SYNCHRONIZE. Параметр lpName является оканчивающейся 0 строкой с именем семафора. При вызове RtOpenSemaphore система сканирует все существующие RTSS семафоры на предмет совпадения с именем, указанным в lpName. Если таковой обнаружится, система создаст уникальный для процесса хэндл этого семафора и вернет его вызвавшему потоку. Любой поток в вызывавшем процессе может теперь использовать этот хэндл в любой функции, принимающей в качестве параметра хэндл RTSS семафора. Если семафор с искомым именем не обнаружится, возвращается NULL.

Хотя объект RTSS семафор всегда поддерживается RTSS подсистемой, Win32 программы могут создавать, открывать и ждать RTSS семафоры. Это позволяет осуществлять взаимодействие RTSS и Win32 процессов. Пространство имен семафоров отлично от пространства имен Win32 семафоров.

Использование событий

Событие является объектом синхронизации, чье состояние может быть явным образом установлено посредством вызовов RtSetEvent или RtPulseEvent. Существует два типа событий:

Событие со сбросом вручную (manual-reset) – событие, чье состояние остается свободным (signalled) до тех пор, пока не переведется в занятое (nonsignalled) состояние вызовом RtResetEvent. В свободном состоянии любое количество ждущих потоков или потоков, вызывающих WaitForSingleObject, могут продолжать исполнение.

Событие с автосбросом (auto-reset) – объект, чье состояние остается свободным до тех пор, пока единственный ждущий поток не продолжит выполнение. В этот момент система автоматически переводит объект в занятое состояние. Если нет ожидающих потоков, объект остается свободным.

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

Использование RtCreateEvent

Поток использует RtCreateEvent для создание объекта событие. Создающий объект поток определяет начальное состояние события и его тип (с автосбросом или сбросом вручную). Этот поток может также задавать имя события (а может и не задавать). Потоки других процессов могут открывать хэндлы существующих событий указывая их имя в вызове RtOpenEvent.

Использование RtPulseEvent

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

Использование мьютексов

RTSS мьютекс – это объект синхронизации, чье состояние является свободным (signalled), когда им не владеет ни один поток, в противном случае он считается занятым (mutex signalled). Мьютекс используется для поочередного доступа к разделяемым ресурсам.

Владение мьютексом

Поток владеет мьютексом от момента выхода из wait функции до вызова RtReleaseMutex. Ни один другой поток не может владеть мьютексом в этом промежутке. Если другой поток вызывает wait функцию в то время, когда мьютекс занят (not signalled), wait функция не вернет управление до тех пор, пока владелец мьютекса его не освободит. Когда владеющий поток заканчивает исполнение, мьютекс переходит в свободное состояние и теряет владельца. Ожидающий поток узнает об “осиротевшем” мьютексе по результату, возвращаемому wait функцией.

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

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

Межпроцессное взаимодействие с использованием мьютексов

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

Использование RtCreateMutex

Наиболее простой способ заключается в том, чтобы один поток в каждом процессе вызвал RtCreateMutex,, передавая идентичную строку-имя мьютекса в качестве параметра. Первый поток, вызвавший RtCreateMutex, заставит систему создать RTSS мьютекс. Когда остальные потоки будут вызывать RtCreateMutex, система определит, что мьютекс с указанным именем уже существует; в результате новый мьютекс не создастся, а функция возвратит уникальный для процесса хэндл, идентифицирующий существующий мьютекс.
Поток может определить, создал ли вызов RtCreateMutex новый мьютекс с помощью вызова функции GetLastError сразу после вызова RtCreateMutex. Если GetLastError вернет ERROR_ALREADY_EXISTS, то новый мьютекс не был создан. Если планируется разделять RTSS мьютекс c другими процессами, последний шаг можно игнорировать.

Использование RtOpenMutex

RtOpenMutex возвращает хэндл RTSS мьютекса. Параметр dwDesiredAccess может принимать значения SEMAPHORE_ALL_ACCESS и SYNCHRONIZE. Параметр lpName является оканчивающейся 0 строкой с именем мьютекса. При вызове RtOpenSemaphore система сканирует все существующие RTSS мьютексы на предмет совпадения с именем, указанным в lpName. Если таковой обнаружится, система создаст уникальный для процесса хэндл этого мьютекса и вернет его вызвавшему потоку. Любой поток в вызывавшем процессе может теперь использовать этот хэндл в любой функции, принимающей в качестве параметра хэндл RTSS мьютекса. Если мьютекс с искомым именем не обнаружится, возвращается NULL.

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

Назад | Содержание | Вперед