Читаем Windows® Internals, Sixth Edition, Part 1 полностью

Waiting for Dispatcher Objects

A thread can synchronize with a dispatcher object by waiting for the object’s handle. Doing so causes the kernel to put the thread in a wait state.

At any given moment, a synchronization object is in one of two states: signaled state or nonsignaled state. A thread can’t resume its execution until its wait is satisfied, a condition that occurs when the dispatcher object whose handle the thread is waiting for also undergoes a state change, from the nonsignaled state to the signaled state (when another thread sets an event object, for example). To synchronize with an object, a thread calls one of the wait system services that the object manager supplies, passing a handle to the object it wants to synchronize with. The thread can wait for one or several objects and can also specify that its wait should be canceled if it hasn’t ended within a certain amount of time. Whenever the kernel sets an object to the signaled state, one of the kernel’s signal routines checks to see whether any threads are waiting for the object and not also waiting for other objects to become signaled. If there are, the kernel releases one or more of the threads from their waiting state so that they can continue executing.

The following example of setting an event illustrates how synchronization interacts with thread dispatching:

A user-mode thread waits for an event object’s handle.

The kernel changes the thread’s scheduling state to waiting and then adds the thread to a list of threads waiting for the event.

Another thread sets the event.

The kernel marches down the list of threads waiting for the event. If a thread’s conditions for waiting are satisfied (see the following note), the kernel takes the thread out of the waiting state. If it is a variable-priority thread, the kernel might also boost its execution priority. (For details on thread scheduling, see Chapter 5.)

Note

Some threads might be waiting for more than one object, so they continue waiting, unless they specified a WaitAny wait, which will wake them up as soon as one object (instead of all) is signaled.

What Signals an Object?

The signaled state is defined differently for different objects. A thread object is in the nonsignaled state during its lifetime and is set to the signaled state by the kernel when the thread terminates. Similarly, the kernel sets a process object to the signaled state when the process’ last thread terminates. In contrast, the timer object, like an alarm, is set to “go off” at a certain time. When its time expires, the kernel sets the timer object to the signaled state.

When choosing a synchronization mechanism, a program must take into account the rules governing the behavior of different synchronization objects. Whether a thread’s wait ends when an object is set to the signaled state varies with the type of object the thread is waiting for, as Table 3-19 illustrates.

Table 3-19. Definitions of the Signaled State

Object Type

Set to Signaled State When

Effect on Waiting Threads

Process

Last thread terminates

All are released.

Thread

Thread terminates

All are released.

Event (notification type)

Thread sets the event

All are released.

Event (synchronization type)

Thread sets the event

One thread is released and might receive a boost; the event object is reset.

Gate (locking type)

Thread signals the gate

First waiting thread is released and receives a boost.

Gate (signaling type)

Thread signals the type

First waiting thread is released.

Keyed event

Thread sets event with a key

Thread that’s waiting for the key and which is of the same process as the signaler is released.

Semaphore

Semaphore count drops by 1

One thread is released.

Timer (notification type)

Set time arrives, or time interval expires

All are released.

Timer (synchronization type)

Set time arrives, or time interval expires

One thread is released.

Mutex

Thread releases the mutex

One thread is released and takes ownership of the mutex.

Queue

Item is placed on queue

One thread is released.

When an object is set to the signaled state, waiting threads are generally released from their wait states immediately. Some of the kernel dispatcher objects and the system events that induce their state changes are shown in Figure 3-26.

For example, a notification event object (called a manual reset event in the Windows API) is used to announce the occurrence of some event. When the event object is set to the signaled state, all threads waiting for the event are released. The exception is any thread that is waiting for more than one object at a time; such a thread might be required to continue waiting until additional objects reach the signaled state.

Перейти на страницу:

Похожие книги