《Win32多线程程序设计》学习笔记 第4章 同步控制之 事件(Event Objects) 和 interlocked variables
event
Event对象是一种核心对象,它的唯一目的就是成为激发状态或者未激发状态。这两种状态全由程序来控制,不会成为Wait..()函数的副作用。他们的状态完全在你的掌控之下。Mutex和semaphore就不同了,他们的状态会因为诸如WaitForSingleObject()之类的函数调用而变化。所以,你可以精确地告诉一个event对象做了什么事,以及什么时候做。
创建event对象
Creates or opens a named or unnamed event object.
HANDLE WINAPI CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes, //安全属性
BOOL bManualReset, //如未FALSE,表示这个event将在变成激发状态(因而唤醒一个线程)之后,自动重置为(reset)未非激发状态,如果为TRUE,表示不会自动重置,必须靠程序操作(调用ResetEvent)才能将激发状态的event重置为非激发状态。
BOOL bInitialState, //如果为true,表示这个event一开始处于激发状态。如果FALSE,则表示这个event一开始处于非激发状态。
LPCTSTR lpName //event的名称。
);
返回值:如果成功,会传回一个eventhandle,失败传回null。
HANDLE WINAPI CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes, //安全属性
BOOL bManualReset, //如未FALSE,表示这个event将在变成激发状态(因而唤醒一个线程)之后,自动重置为(reset)未非激发状态,如果为TRUE,表示不会自动重置,必须靠程序操作(调用ResetEvent)才能将激发状态的event重置为非激发状态。
BOOL bInitialState, //如果为true,表示这个event一开始处于激发状态。如果FALSE,则表示这个event一开始处于非激发状态。
LPCTSTR lpName //event的名称。
);
返回值:如果成功,会传回一个eventhandle,失败传回null。
使用event对象
- SetEvent(): 把event对象设为激发状态。
- ResetEvent(): 把event对象设为非激发状态。
- PulseEvent():如果是一个manual reset event:把event对象设为激发状态,唤醒所有的等待中的线程,然后event恢复为非激发状态。 如果是一个auto reset event:把event对象设为激发状态,唤醒一个等待中的线程,然后event恢复为非激发状态。
Interlocked Variables
同步机制的最简单类型是使用interlocked 函数,对着标准的32位变量进行操作。这些函数并没有提供“等待”机能,他们只是保证对某个特定变量的存取操作是“一个一个接顺序来”。所谓的interlocked函数,有2个:interlockedIncrement()和interlockedDecrement():
Increments (increases by one) the value of the specified 32-bit variable as an atomic operation.To operate on 64-bit values, use the InterlockedIncrement64 function.
LONG __cdecl InterlockedIncrement(
LONG volatile* Addend //A pointer to the variable to be incremented.
);
Return Value
The function returns the resulting incremented value.
/////////////////////////////////////////////////////////////////////////////
Decrements (decreases by one) the value of the specified 32-bit variable as an atomic operation. To operate on 64-bit values, use the InterlockedDecrement64 function.
LONG __cdecl InterlockedDecrement(
LONG volatile* Addend //A pointer to the variable to be decremented.
);
Return Value
The function returns the resulting decremented value.
LONG __cdecl InterlockedIncrement(
LONG volatile* Addend //A pointer to the variable to be incremented.
);
Return Value
The function returns the resulting incremented value.
/////////////////////////////////////////////////////////////////////////////
Decrements (decreases by one) the value of the specified 32-bit variable as an atomic operation. To operate on 64-bit values, use the InterlockedDecrement64 function.
LONG __cdecl InterlockedDecrement(
LONG volatile* Addend //A pointer to the variable to be decremented.
);
Return Value
The function returns the resulting decremented value.
interlockedExchange()可以设定一个新值并传回旧值。就想以上2个函数一样。提供了在多线程环境下的安全做法。
Sets a 32-bit variable to the specified value as an atomic operation. To operate on a pointer variable, use the InterlockedExchangePointer function.
LONG __cdecl InterlockedExchange(
LONG volatile* Target, //32位变量的地址。必须指向 long word
LONG Value //用以取代Target所指内容的新值
);
返回值: 传回先前由lpTarget所指的内容。
LONG __cdecl InterlockedExchange(
LONG volatile* Target, //32位变量的地址。必须指向 long word
LONG Value //用以取代Target所指内容的新值
);
返回值: 传回先前由lpTarget所指的内容。