c++多线程8event
2012-08-20 15:03
225 查看
一 Event
在所有的内核对象中,事件内核对象是个最基本的对象。它们包含一个使用计数(与所有内核对象一样),一个用于指明该事件是个自动重置的事件还是一个人工重置的事件的布尔值,另一个用于指明该事件处于已通知状态还是未通知状态的布尔值。
事件能够通知一个操作已经完成。有两种不同类型的事件对象。一种是人工重置的事件,另一种是自动重置的事件。当人工重置的事件得到通知时,等待该事件的所有线程均变为可调度线程。当一个自动重置的事件得到通知时,等待该事件的线程中只有一个线程变为可调度线程。
当一个线程执行初始化操作,然后通知另一个线程执行剩余的操作时,事件使用得最多。事件初始化为未通知状态,然后,当该线程完成它的初始化操作后,它就将事件设置为已通知状态。这时,一直在等待该事件的另一个线程发现该事件已经得到通知,因此它就变成可调度线程。
Microsoft为自动重置的事件定义了应该成功等待的副作用规则,即当线程成功地等待到该对象时,自动重置的事件就会自动重置到未通知状态。这就是自动重置的事件如何获得它们的名字的方法。通常没有必要为自动重置的事件调用ResetEvent函数,因为系统会自动对事件进行重置。但是,Microsoft没有为人工重置的事件定义成功等待的副作用,所以需要调用ResetEvent()。
二 Event APIEvent function Description
CreateEvent Creates or opens a named or unnamed event object.
CreateEventEx Creates or opens a named or unnamed event object and returns a handle to the object.
OpenEvent Opens an existing named event object.
PulseEventSets the specified event object to the signaled state and then resets it to the nonsignaled state after releasing the appropriate number of waiting threads.
ResetEvent Sets the specified event object to the nonsignaled state.
SetEvent Sets the specified event object to the signaled state.
三 代码实例
1)使用手动的Event:当文件读入内存的时候,WordCount, SpellCheck,GrammarCheck可以同时进行,这里使用Event,当文件一读入内存就通知WordCount,SpellCheck和GrammarCheck线程开始执行。
#include <windows.h>
#include <process.h>
#include <stdio.h>
// a global handle to event.
HANDLE g_hEvent;
void OpenFileAndReadContentsIntoMemory();
unsigned __stdcall WordCount(void *pvParam);
unsigned __stdcall SpellCheck(void *pvParam);
unsigned __stdcall GrammarCheck(void *pvParam);
int main()
{
//Create the manual-reset, nonsignaled event.
g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
//Spawn 3 new threads.
HANDLE hThread[3];
unsigned dwThreadID[3];
hThread[0] = (HANDLE)_beginthreadex(NULL, 0, WordCount, NULL, 0, &dwThreadID[0]);
hThread[1] = (HANDLE)_beginthreadex(NULL, 0, SpellCheck, NULL, 0, &dwThreadID[1]);
hThread[2] = (HANDLE)_beginthreadex(NULL, 0, GrammarCheck, NULL, 0, &dwThreadID[2]);
OpenFileAndReadContentsIntoMemory();
//Allow all 3 threads to access the memory.
SetEvent(g_hEvent);
printf("main thread exit/n");
return 1;
}
void OpenFileAndReadContentsIntoMemory()
{
printf("Open File and Read contents into memory/n");
}
unsigned __stdcall WordCount(void *pvParam)
{
//Wait until the file's data is in memory.
WaitForSingleObject(g_hEvent, INFINITE);
//Access the memory block.
printf("0:word count/n");
return(0);
}
unsigned __stdcall SpellCheck(void *pvParam)
{
//Wait until the file's data is in memory.
WaitForSingleObject(g_hEvent, INFINITE);
//Access the memory block.
printf("1:Spell check/n");
return(0);
}
unsigned __stdcall GrammarCheck(void *pvParam)
{
//Wait until the file's data is in memory.
WaitForSingleObject(g_hEvent, INFINITE);
//Access the memory block.
printf("2:Grammar check/n");
return(0);
}
2)修改上面的代码,使用自动Event,则必须在3个子线程中增加SetEvent()。且要想让3个线程都执行完,必须的增加Waitfor()函数。
#include <windows.h>
#include <process.h>
#include <stdio.h>
// a global handle to event.
HANDLE g_hEvent;
void OpenFileAndReadContentsIntoMemory();
unsigned __stdcall WordCount(void *pvParam);
unsigned __stdcall SpellCheck(void *pvParam);
unsigned __stdcall GrammarCheck(void *pvParam);
int main()
{
//Create the AUTO-reset, nonsignaled event.
g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
//Spawn 3 new threads.
HANDLE hThread[3];
unsigned dwThreadID[3];
hThread[0] = (HANDLE)_beginthreadex(NULL, 0, WordCount, NULL, 0, &dwThreadID[0]);
hThread[1] = (HANDLE)_beginthreadex(NULL, 0, SpellCheck, NULL, 0, &dwThreadID[1]);
hThread[2] = (HANDLE)_beginthreadex(NULL, 0, GrammarCheck, NULL, 0, &dwThreadID[2]);
OpenFileAndReadContentsIntoMemory();
//Allow all 3 threads to access the memory.
SetEvent(g_hEvent);
//wait for child threads to exit
DWORD dwCThd = WaitForMultipleObjects (3, //count of objects
hThread, //thread handle
TRUE, //wait for all
INFINITE); //time out interval
if(dwCThd != WAIT_OBJECT_0)
{
printf("error/n");
exit(-1);
}
//close handles
CloseHandle (g_hEvent);
//close child thread handles
for (int i=0; i<3; i++)
CloseHandle (hThread[i]);
printf("main thread exit/n");
return 1;
}
void OpenFileAndReadContentsIntoMemory()
{
printf("Open File and Read contents into memory/n");
}
unsigned __stdcall WordCount(void *pvParam)
{
//Wait until the file's data is in memory.
WaitForSingleObject(g_hEvent, INFINITE);
//Access the memory block.
printf("0:word count/n");
SetEvent(g_hEvent);
return(0);
}
unsigned __stdcall SpellCheck(void *pvParam)
{
//Wait until the file's data is in memory.
WaitForSingleObject(g_hEvent, INFINITE);
//Access the memory block.
printf("1:Spell check/n");
SetEvent(g_hEvent);
return(0);
}
unsigned __stdcall GrammarCheck(void *pvParam)
{
//Wait until the file's data is in memory.
WaitForSingleObject(g_hEvent, INFINITE);
//Access the memory block.
printf("2:Grammar check/n");
SetEvent(g_hEvent);
return(0);
}
在所有的内核对象中,事件内核对象是个最基本的对象。它们包含一个使用计数(与所有内核对象一样),一个用于指明该事件是个自动重置的事件还是一个人工重置的事件的布尔值,另一个用于指明该事件处于已通知状态还是未通知状态的布尔值。
事件能够通知一个操作已经完成。有两种不同类型的事件对象。一种是人工重置的事件,另一种是自动重置的事件。当人工重置的事件得到通知时,等待该事件的所有线程均变为可调度线程。当一个自动重置的事件得到通知时,等待该事件的线程中只有一个线程变为可调度线程。
当一个线程执行初始化操作,然后通知另一个线程执行剩余的操作时,事件使用得最多。事件初始化为未通知状态,然后,当该线程完成它的初始化操作后,它就将事件设置为已通知状态。这时,一直在等待该事件的另一个线程发现该事件已经得到通知,因此它就变成可调度线程。
Microsoft为自动重置的事件定义了应该成功等待的副作用规则,即当线程成功地等待到该对象时,自动重置的事件就会自动重置到未通知状态。这就是自动重置的事件如何获得它们的名字的方法。通常没有必要为自动重置的事件调用ResetEvent函数,因为系统会自动对事件进行重置。但是,Microsoft没有为人工重置的事件定义成功等待的副作用,所以需要调用ResetEvent()。
二 Event APIEvent function Description
CreateEvent Creates or opens a named or unnamed event object.
CreateEventEx Creates or opens a named or unnamed event object and returns a handle to the object.
OpenEvent Opens an existing named event object.
PulseEventSets the specified event object to the signaled state and then resets it to the nonsignaled state after releasing the appropriate number of waiting threads.
ResetEvent Sets the specified event object to the nonsignaled state.
SetEvent Sets the specified event object to the signaled state.
三 代码实例
1)使用手动的Event:当文件读入内存的时候,WordCount, SpellCheck,GrammarCheck可以同时进行,这里使用Event,当文件一读入内存就通知WordCount,SpellCheck和GrammarCheck线程开始执行。
#include <windows.h>
#include <process.h>
#include <stdio.h>
// a global handle to event.
HANDLE g_hEvent;
void OpenFileAndReadContentsIntoMemory();
unsigned __stdcall WordCount(void *pvParam);
unsigned __stdcall SpellCheck(void *pvParam);
unsigned __stdcall GrammarCheck(void *pvParam);
int main()
{
//Create the manual-reset, nonsignaled event.
g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
//Spawn 3 new threads.
HANDLE hThread[3];
unsigned dwThreadID[3];
hThread[0] = (HANDLE)_beginthreadex(NULL, 0, WordCount, NULL, 0, &dwThreadID[0]);
hThread[1] = (HANDLE)_beginthreadex(NULL, 0, SpellCheck, NULL, 0, &dwThreadID[1]);
hThread[2] = (HANDLE)_beginthreadex(NULL, 0, GrammarCheck, NULL, 0, &dwThreadID[2]);
OpenFileAndReadContentsIntoMemory();
//Allow all 3 threads to access the memory.
SetEvent(g_hEvent);
printf("main thread exit/n");
return 1;
}
void OpenFileAndReadContentsIntoMemory()
{
printf("Open File and Read contents into memory/n");
}
unsigned __stdcall WordCount(void *pvParam)
{
//Wait until the file's data is in memory.
WaitForSingleObject(g_hEvent, INFINITE);
//Access the memory block.
printf("0:word count/n");
return(0);
}
unsigned __stdcall SpellCheck(void *pvParam)
{
//Wait until the file's data is in memory.
WaitForSingleObject(g_hEvent, INFINITE);
//Access the memory block.
printf("1:Spell check/n");
return(0);
}
unsigned __stdcall GrammarCheck(void *pvParam)
{
//Wait until the file's data is in memory.
WaitForSingleObject(g_hEvent, INFINITE);
//Access the memory block.
printf("2:Grammar check/n");
return(0);
}
2)修改上面的代码,使用自动Event,则必须在3个子线程中增加SetEvent()。且要想让3个线程都执行完,必须的增加Waitfor()函数。
#include <windows.h>
#include <process.h>
#include <stdio.h>
// a global handle to event.
HANDLE g_hEvent;
void OpenFileAndReadContentsIntoMemory();
unsigned __stdcall WordCount(void *pvParam);
unsigned __stdcall SpellCheck(void *pvParam);
unsigned __stdcall GrammarCheck(void *pvParam);
int main()
{
//Create the AUTO-reset, nonsignaled event.
g_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
//Spawn 3 new threads.
HANDLE hThread[3];
unsigned dwThreadID[3];
hThread[0] = (HANDLE)_beginthreadex(NULL, 0, WordCount, NULL, 0, &dwThreadID[0]);
hThread[1] = (HANDLE)_beginthreadex(NULL, 0, SpellCheck, NULL, 0, &dwThreadID[1]);
hThread[2] = (HANDLE)_beginthreadex(NULL, 0, GrammarCheck, NULL, 0, &dwThreadID[2]);
OpenFileAndReadContentsIntoMemory();
//Allow all 3 threads to access the memory.
SetEvent(g_hEvent);
//wait for child threads to exit
DWORD dwCThd = WaitForMultipleObjects (3, //count of objects
hThread, //thread handle
TRUE, //wait for all
INFINITE); //time out interval
if(dwCThd != WAIT_OBJECT_0)
{
printf("error/n");
exit(-1);
}
//close handles
CloseHandle (g_hEvent);
//close child thread handles
for (int i=0; i<3; i++)
CloseHandle (hThread[i]);
printf("main thread exit/n");
return 1;
}
void OpenFileAndReadContentsIntoMemory()
{
printf("Open File and Read contents into memory/n");
}
unsigned __stdcall WordCount(void *pvParam)
{
//Wait until the file's data is in memory.
WaitForSingleObject(g_hEvent, INFINITE);
//Access the memory block.
printf("0:word count/n");
SetEvent(g_hEvent);
return(0);
}
unsigned __stdcall SpellCheck(void *pvParam)
{
//Wait until the file's data is in memory.
WaitForSingleObject(g_hEvent, INFINITE);
//Access the memory block.
printf("1:Spell check/n");
SetEvent(g_hEvent);
return(0);
}
unsigned __stdcall GrammarCheck(void *pvParam)
{
//Wait until the file's data is in memory.
WaitForSingleObject(g_hEvent, INFINITE);
//Access the memory block.
printf("2:Grammar check/n");
SetEvent(g_hEvent);
return(0);
}
相关文章推荐
- c++多线程时 undefined reference to 'pthread_create'问题解决
- c++多线程使用printf输出的bug
- C++多线程
- c++多线程 及mutex锁
- c++多线程(四)
- C++多线程之使用Mutex和Critical_Section
- C++多线程框架-----Mutex互斥和Sem信号量
- [置顶] c++多线程(多线程处理vector)
- C++多线程编程总结
- C++多线程实例
- C++多线程之使用Mutex和Critical_Section
- c++多线程编程1----具体概念理解
- C++多线程(四)
- C++多线程编程入门之经典实例
- c++多线程编程:常见面试题
- C++多线程(九)
- C++多线程实例之临界区同步
- C++多线程-第三篇-Thread(线程)
- C++多线程编程——线程的挂起、唤醒与终止
- C++多线程实例-信号量