C++ Programmer's Cookbook

{C++ 基础} {C++ 高级} {C#界面,C++核心算法} {设计模式} {C#基础}

C++多线程(八)

多线程同步之Event(主要用来线程间的等待通知
 
一 Event
     在所有的内核对象中,事件内核对象是个最基本的对象。它们包含一个使用计数(与所有内核对象一样),一个用于指明该事件是个自动重置的事件还是一个人工重置的事件的布尔值,另一个用于指明该事件处于已通知状态还是未通知状态的布尔值。

        事件能够通知一个操作已经完成。有两种不同类型的事件对象。一种是人工重置的事件,另一种是自动重置的事件。当人工重置的事件得到通知时,等待该事件的所有线程均变为可调度线程。当一个自动重置的事件得到通知时,等待该事件的线程中只有一个线程变为可调度线程。

        当一个线程执行初始化操作,然后通知另一个线程执行剩余的操作时,事件使用得最多。事件初始化为未通知状态,然后,当该线程完成它的初始化操作后,它就将事件设置为已通知状态。这时,一直在等待该事件的另一个线程发现该事件已经得到通知,因此它就变成可调度线程。

         Microsoft为自动重置的事件定义了应该成功等待的副作用规则,即当线程成功地等待到该对象时,自动重置的事件就会自动重置到未通知状态。这就是自动重置的事件如何获得它们的名字的方法。通常没有必要为自动重置的事件调用ResetEvent函数,因为系统会自动对事件进行重置。但是,Microsoft没有为人工重置的事件定义成功等待的副作用,所以需要调用ResetEvent()。

二 Event API

Event 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.
PulseEvent Sets 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);
}

四 参考
windows核心编程

posted on 2007-07-31 14:59 梦在天涯 阅读(4493) 评论(5)  编辑 收藏 引用 所属分类: CPlusPlus

评论

# re: C++多线程(八)[未登录] 2007-08-01 08:34 漂舟

这一系列标题写得有误解, 看着总有上当的感觉,
应该叫 Windows多线程 吧。  回复  更多评论   

# re: C++多线程(八) 2007-08-01 09:00 梦在天涯

应该是C++多线程在windows上的实现。  回复  更多评论   

# re: C++多线程(八)[未登录] 2007-08-01 21:39 创系

建议LZ把题目改为"windows 多线程"。  回复  更多评论   

# re: C++多线程(八) 2007-10-26 11:11 zhang-gq

不错。谢谢。  回复  更多评论   

# re: C++多线程(八) 2009-06-10 14:47 aniki

学习中,以前用过.net封装后的event,看到这块似曾相识啊  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


公告

EMail:itech001#126.com

导航

统计

  • 随笔 - 461
  • 文章 - 4
  • 评论 - 746
  • 引用 - 0

常用链接

随笔分类

随笔档案

收藏夹

Blogs

c#(csharp)

C++(cpp)

Enlish

Forums(bbs)

My self

Often go

Useful Webs

Xml/Uml/html

搜索

  •  

积分与排名

  • 积分 - 1796890
  • 排名 - 5

最新评论

阅读排行榜