Windows中线程间同步的方法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Windows中线程间同步的方法主要有:事件(Event)、临界区(Critical Section)、互斥量(Mutex)和信号灯(Semaphore)。
1)使用事件对象进行线程间同步:
在使用CreateEvent函数创建事件对象时,将bManualReset参数设置为FALSE,然后在需要独占操作的代码前面加上一个WaitForSingleObject函数,后面加上一个SetEvent即可。
由于bManualReset参数为FALSE,这样当某个线程等待到Event后,Event对象的状态马上就变为复位状态,这样其他线程执行到WaitForSingleObject时就全部处于等待中了,当活动的线程操作完毕后,执行SetEvent函数,Event对象的状态才恢复到置位,这样其他等待的线程才会有一个能继续操作。
SetEvent函数原型如下:
HANDLE WINAPI CreateEvent(
__in_opt LPSECURITY_ATTRIBUTES lpEventAttributes, //安全描述符
__in BOOL bManualReset, //指定事件对象是否需要手动复位
__in BOOL bInitialState, //指定事件对象创建时的初始状态,为TRUE表示初始状态是置位状态;
//为FALSE表示初始状态是复位状态
__in_opt LPCTSTR lpName //指定事件对象名称
);
当一个事件被创建后,程序就可以通过SetEvent和ResetEvent函数来设置事件的状态:BOOL WINAPI SetEvent(
__in HANDLE hEvent
);
BOOL WINAPI ResetEvent(
__in HANDLE hEvent
);
事件对象不仅可以用于一个进程中多线程同步,还可以用于多进程中的线程同步,只要在创建事件对象时指定事件名字,在其他进程中可以使用OpenEvent函数根据名称打开该事件对象进行使用:
HANDLE WINAPI OpenEvent(
__in DWORD dwDesiredAccess, //对事件对象的访问限制
__in BOOL bInheritHandle, //子进程是否继承该事件句柄
__in LPCTSTR lpName //事件对象的名字
);
实例代码如下:
#include
#include
#define THREADCOUNT 4
HANDLE ghWriteEvent;
HANDLE ghThreads[THREADCOUNT];
DWORD WINAPI ThreadProc(LPVOID);
void CreateEventsAndThreads(void)
{
int i;
DWORD dwThreadID;
// Create a manual-reset event object. The write thread sets this // object to the nonsignaled state when it finishes writing to a
// shared buffer.
ghWriteEvent = CreateEvent(
NULL, // default security attributes
TRUE, // manual-reset event
FALSE, // initial state is nonsignaled
TEXT("WriteEvent") // object name
);
if (ghWriteEvent == NULL)
{
printf("CreateEvent failed (%d)\n", GetLastError());
return;
}
// Create multiple threads to read from the buffer.
for(i = 0; i < THREADCOUNT; i++)
{
// TODO: More complex scenarios may require use of a parameter // to the thread procedure, such as an event per thread to
// be used for synchronization.
ghThreads[i] = CreateThread(
NULL, // default security
0, // default stack size
ThreadProc, // name of the thread function
NULL, // no thread parameters
0, // default startup flags
&dwThreadID);
if (ghThreads[i] == NULL)
{
printf("CreateThread failed (%d)\n", GetLastError());
return;
}
}
void WriteToBuffer(VOID)
{
// TODO: Write to the shared buffer.
printf("Main thread writing to the shared buffer...\n");
// Set ghWriteEvent to signaled
if (! SetEvent(ghWriteEvent) )
{
printf("SetEvent failed (%d)\n", GetLastError());
return;
}
}
void CloseEvents()
{
// Close all event handles (currently, only one global handle).
CloseHandle(ghWriteEvent);