复习笔记之三--内核对象线程同步---事件

来源:互联网 发布:企业网软件下载 编辑:程序博客网 时间:2024/05/17 21:58
1、     等待函数

//**************************************************************//

//输入参数:hHandle 标识一个支持被通知/未通知的内核对象,dwMilliseconds 等待的时间,INFINITE为等待直到进程结束。

//****见返回值******************************//

//****函数作用:线程自愿进入等待状态,直到锁等待的对象被通知  **********//

//*************************************************************//

 
DWORD WINAPI WaitForSingleObject(
  __in  HANDLE hHandle,
  __in  DWORD dwMilliseconds
);

返回值:

WAIT_OBJECT_0                        等待的对象被通知,等待成功。

0x00000000L

WAIT_TIMEOUT                等待超时,超出dwMilliseconds规定时间

0x00000102L

WAIT_FAILED                 等待失败  GetLastError.获得失败原因

(DWORD)0xFFFFFFFF

 

//**************************************************************//

//输入参数:nCount 等待对象的个数,hHandle 标识一个支持被通知/未通知的内核对象的数组,bWaitAll 等待方式,true:所有对象被通知之前,不允许调用线程运行、false:对象之一得到通知,就返回。dwMilliseconds 等待的时间,INFINITE为等待直到进程结束。

//****见返回值******************************//

//****函数作用:线程自愿进入等待状态,直到锁等待的对象被通知  **********//

//*************************************************************//

DWORD WINAPI WaitForMultipleObjects(
  __in  DWORD nCount,
  __in  const HANDLE *lpHandles,
  __in  BOOL bWaitAll,
  __in  DWORD dwMilliseconds
);
返回值:
     
bWaitAll 传递 true:
     

WAIT_OBJECT_0               等待的所有对象被通知,等待成功。

0x00000000L

WAIT_TIMEOUT                等待超时,超出dwMilliseconds规定时间

0x00000102L

WAIT_FAILED                 等待失败  GetLastError.获得失败原因

(DWORD)0xFFFFFFFF

bWaitAll 传递 false:
 

WAIT_OBJECT_0--WAIT_OBJECT_ nCount-1    等待的哪一个对象被通知,等待成功。

0x00000000L-----

WAIT_TIMEOUT                等待超时,超出dwMilliseconds规定时间

0x00000102L

WAIT_FAILED                 等待失败  GetLastError.获得失败原因

(DWORD)0xFFFFFFFF

2、     事件内核对象同步

执行原理:线程进入等待状态,利用事件内核通知原理同步线程。事件内核默认处于未通知状态。

应用:应用于多个线程需要按照一定顺序执行的应用程序,如:线程1 进行初始化变量X,线程2中使用变量X。

函数1:

//**************************************************************//

//输入参数:lpEventAttributes  安全性设置,类似创建线程的安全性设置。

bManualReset:true 人工重置事件 :等待该事件的所有线程置为可调用状态

                            false 自动重置事件:等待该事件的线程只有一个可调用。

                            采用先进先出算法进行调度。

bInitialState:指明事件初始化事的状态,true:已通知事件;false:未通知事件

lpName       :事件名称(用于事件定位,如打开事件)

//****输出:事件句柄,若失败,可使用GetLastError************//

//****函数作用:创建一个事件  **********//

//*************************************************************//

HANDLE WINAPI CreateEvent(
  __in_opt  LPSECURITY_ATTRIBUTES lpEventAttributes,
  __in      BOOL bManualReset,
  __in      BOOL bInitialState,
  __in_opt  LPCTSTR lpName
);
注意:句柄不在使用时,使用CloseHandle(hHandle);关闭句柄

函数2:

//**************************************************************//

//输入参数:dwDesiredAccess 打开的安全描述,一般为NULL

bInheritHandletrue :打开成功,进程继承此句柄

                                false:打开成功,进程不继承此句柄

lpName       :事件名称

//****输出:事件句柄,若失败,可使用GetLastError************//

//****函数作用:打开一个事件获得事件句柄  **********//

//*************************************************************//

HANDLE WINAPI OpenEvent(
  __in  DWORD dwDesiredAccess,
  __in  BOOL bInheritHandle,
  __in  LPCTSTR lpName
);

函数3:

//**************************************************************//

//输入参数:hEvent 事件句柄,通过新建或者打开事件获得***********//

//****输出:成功返回非 0 ;失败 返回0 GetLastError************//

//****函数作用:设置事件为已通知状态  **********//

//*************************************************************//

BOOL WINAPI SetEvent(
  __in  HANDLE hEvent
);

      对应 :

BOOL WINAPI ResetEvent(     //设置事件为未通知状态,继续等待
  __in  HANDLE hEvent
);
Example:
 

#include "stdafx.h"

#include <Windows.h>

#include <Tlhelp32.h>

#include <process.h>

static const char buffer[80] = {'1','5','2','0','0','0','0','9','0','0','3','\n', '1','5','2','0','0','0','0','9','0','0','4','\n',

'1','5','2','0','0','0','0','9','0','0','5','\n', '1','5','2','0','0','0','0','9','0','0','6','\n', '1','5','2','0','0','0','0','9','0','0','7','\n', '1','5','2','0','0','0','0','9','0','0','8','\n',

};

HANDLE g_tellgo1;

HANDLE g_tellgo2;

HANDLE g_tellOver;

DWORD WINAPI Go1(PVOID pvparam)

{

FILE * hFile = fopen("C:/dian.txt","r+");

if (!hFile)

{

return 0;

}

fwrite(buffer,sizeof(char),80,hFile);

fclose(hFile);

SetEvent(g_tellgo1);

// 将g_tellgo2 置为通知状态,等待 g_tellgo1

//SignalObjectAndWait(g_tellgo2,g_tellgo1,INFINITE,NULL);

return 0;

}

DWORD WINAPI Go2(PVOID pvparam)

{

WaitForSingleObject(g_tellgo2,INFINITE);

char buf[80];

FILE * hFile = fopen("C:/dian.txt","r+");

if (!hFile)

{

return 0;

}

fread(buf,sizeof(char),80,hFile);

printf("%.80s",buf);

fclose(hFile);

SetEvent(g_tellOver);

return 0;

}

DWORD WINAPI Go3(PVOID pvparam)

{

WaitForSingleObject(g_tellgo1,INFINITE);

char buf[6]={'a','b','c','d','e','\n'};

FILE * hFile = fopen("C:/dian.txt","r+");

if (!hFile)

{

return 0;

}

fwrite(buf,sizeof(char),6,hFile);

fclose(hFile);

SetEvent(g_tellgo2);

return 0;

}

DWORD WINAPI Go4(PVOID pvparam)

{

return 0;

}

int _tmain(int argc, _TCHAR* argv[])

{

g_tellgo1 = CreateEvent(NULL,false,false,NULL);

g_tellgo2 = CreateEvent(NULL,false,false,NULL);

g_tellOver = CreateEvent(NULL,false,false,NULL);

DWORD Threadone;

DWORD Threadtwo;

DWORD Threadthree;

DWORD Threadfour;

HANDLE Thread1= CreateThread(NULL,0,Go1,0,0,&Threadone);

HANDLE Thread2= CreateThread(NULL,0,Go2,0,0,&Threadtwo);

HANDLE Thread3= CreateThread(NULL,0,Go3,0,0,&Threadthree);

HANDLE h[4];

h[0] = Thread1;

h[1] = Thread2;

h[2] = Thread3;

h[3] = g_tellOver;

DWORD DW= WaitForMultipleObjects(4, h, TRUE, INFINITE);

CloseHandle(g_tellgo1);

CloseHandle(g_tellgo2);

CloseHandle(g_tellOver);

CloseHandle(Thread1);

CloseHandle(Thread2);

CloseHandle(Thread3);

system("pause");

return 0;

}

0 0