windows C/C++ 內核對象、事件對象、信號量

承接上一篇:https://blog.csdn.net/uVarAndMethod/article/details/90360838 

    1、內核對象:														
		進程、線程、文件、文件映射、事件、互斥體等等														
	
    2、事件內核對象的創建															
	HANDLE g_hEvent = CreateEvent(NULL, TRUE, FALSE, "XYZ");															
	HANDLE g_hMutex = CreateMutex(NULL,FALSE, "XYZ");							
								
	3、事件內核對象的獲取															
	HANDLE OpenEvent(							
	  DWORD dwDesiredAccess,  // access							
	  BOOL bInheritHandle,    // inheritance option							
	  LPCTSTR lpName          // object name							
	);															
	HANDLE g_hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, "XYZ");														
	HANDLE g_hMutex = OpenMutex(MUTEX_ALL_ACCESS,FALSE, "XYZ");							
								
	4、內核對象的銷燬														
	BOOL CloseHandle(HANDLE hobj);														
	(1)、當沒有其他程序引用時,系統會銷燬內核對象(使用數量).														
	(2)、內核對象的生命週期,可能比創建它的對象要長.														
								
	5、內核對象的生命週期														
	eg:CloseHandle()/進程結束														
	進程一:													
	HANDLE g_hEvent = CreateEvent(NULL, TRUE, FALSE, "XYZ");														
	SetEvent(g_hEvent);							
								
								
	進程二:															
	HANDLE g_hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, "XYZ");														
	WaitForSingleObject(g_hEvent, INFINITE);							
																
	eg:內核對象的生命週期															
	進程一:															
	HANDLE g_hEvent = CreateEvent(NULL, TRUE, FALSE, "XYZ");															
	SetEvent(g_hEvent);														
								
	進程二:														
	HANDLE g_hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, "XYZ");													
	WaitForSingleObject(g_hEvent, INFINITE);				
///////////////////////////////////////////////////////////////////////////
1、事件對象的創建								
HANDLE CreateEvent(				
  LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全屬性 NULL時爲系統默認				
  BOOL bManualReset,                       // TRUE 通過調用ResetEvent將事件對象標記爲未通知				
  BOOL bInitialState,                      // TRUE 已通知狀態  FALSE未通知狀態				
  LPCTSTR lpName                           // 對象名稱 以NULL結尾的字符串				
);				
								
2、事件對象的控制								
BOOL SetEvent(HANDLE hEvent);				       //將對象設置爲已通知				

3、關閉時間對象句柄				
				       //關閉句柄
CloseHandle();				
					
4、線程控制實驗:只讀形式的線程控制						
HANDLE g_hEvent;				
				
HWND hEdit1;				
HWND hEdit2;				
HWND hEdit3;				
HWND hEdit4;				
HANDLE hThread1;				
HANDLE hThread2;				
HANDLE hThread3;				
HANDLE hThread4;				
				
DWORD WINAPI ThreadProc1(LPVOID lpParameter)				
{				
	//創建事件			
	//默認安全屬性  手動設置未通知狀態(TRUE)  初始狀態未通知 沒有名字 			
	g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);			
	HANDLE hThread[3];			
	//創建3個線程			
	hThread[0] = ::CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);			
	hThread[1] = ::CreateThread(NULL, 0, ThreadProc3, NULL, 0, NULL);			
	hThread[2] = ::CreateThread(NULL, 0, ThreadProc4, NULL, 0, NULL);			
				
	//設置文本框的值			
	SetWindowText(hEdit1,"1000");			
				
	//設置事件爲已通知			
	SetEvent(g_hEvent);			
				
	//等待線程結束 銷燬內核對象			
	WaitForMultipleObjects(3, hThread, TRUE, INFINITE);  			
	CloseHandle(hThread[0]);  			
	CloseHandle(hThread[1]);			
	CloseHandle(hThread[2]);			
	CloseHandle(g_hEvent);  							
	return 0;			
}				
				
DWORD WINAPI ThreadProc2(LPVOID lpParameter)				
{				
	TCHAR szBuffer[10] = {0};							
	//當事件變成已通知時 			
	WaitForSingleObject(g_hEvent, INFINITE);			
				
	//讀取內容			
	GetWindowText(hEdit1,szBuffer,10);							
	SetWindowText(hEdit2,szBuffer);							
	return 0;			
}				
DWORD WINAPI ThreadProc3(LPVOID lpParameter)				
{				
	TCHAR szBuffer[10] = {0};							
	//當事件變成已通知時 			
	WaitForSingleObject(g_hEvent, INFINITE);						
	//讀取內容			
	GetWindowText(hEdit1,szBuffer,10);						
	SetWindowText(hEdit3,szBuffer);						
	return 0;			
}				
DWORD WINAPI ThreadProc4(LPVOID lpParameter)				
{				
	TCHAR szBuffer[10] = {0};						
	//當事件變成已通知時 			
	WaitForSingleObject(g_hEvent, INFINITE);			
				
	//讀取內容			
	GetWindowText(hEdit1,szBuffer,10);			
				
	SetWindowText(hEdit4,szBuffer);							
	return 0;			
}				
////////////////////////////////////////////////////////////////
	創建信號量					
	HANDLE CreateSemaphore(					
	  LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,					
	  LONG lInitialCount,					
	  LONG lMaximumCount,					
	  LPCTSTR lpName					
	);		
			
	函數說明:					
	第一個參數表示安全控制,一般直接傳入NULL。					
	第二個參數表示初始資源數量。0時不發送信號 					
	第三個參數表示最大併發數量。lInitialCount<=lMaximumCount					
	第四個參數表示信號量的名稱,傳入NULL表示匿名信號量。					
			
	打開信號量				
	HANDLE OpenSemaphore(					
	  DWORD dwDesiredAccess,					
	  BOOL bInheritHandle,				
	  LPCTSTR lpName				
	);		
			
	函數說明:					
	第一個參數表示訪問權限,對一般傳入SEMAPHORE_ALL_ACCESS。詳細解釋可以查看MSDN文檔。				
	第二個參數表示信號量句柄繼承性,一般傳入FALSE即可。				
	第三個參數表示名稱,不同進程中的各線程可以通過名稱來確保它們訪問同一個信號量。					
			
	遞增信號量的當前資源計數		
						
	BOOL ReleaseSemaphore(					
	  HANDLE hSemaphore,					
	  LONG lReleaseCount,  					
	  LPLONG lpPreviousCount 				
	);					
	函數說明:					
	第一個參數是信號量的句柄。					
	第二個參數表示增加個數,必須大於0且不超過最大資源數量。					
	第三個參數返回當前資源數量的原始值,設爲NULL表示不需要傳出。					
	注:沒有一個函數可以用來查詢信標的當前資源數量的值					
			
	信號量的清理與銷燬					
	CloseHandle()		
			
	通過信號量控制對資源的訪問:				
	見MSDN	

    eg:
    					
	信號量應用								
					
	#include "stdafx.h"				
	#include "resource.h"				
	HANDLE hSemaphore;				
	HANDLE hThread[3];				
	HWND hEditSet;				
	HWND hEdit1;				
	HWND hEdit2;				
	HWND hEdit3;				
	DWORD WINAPI ThreadProc1(LPVOID lpParameter)				
	{				
		TCHAR szBuffer[10];			
		DWORD dwTimmer=0;			
		WaitForSingleObject(hSemaphore, INFINITE);			
		while(dwTimmer<100)			
		{			
			Sleep(100);		
			memset(szBuffer,0,10);		
			GetWindowText(hEdit1,szBuffer,10);		
			sscanf( szBuffer, "%d", &dwTimmer );		
			dwTimmer++;		
			memset(szBuffer,0,10);		
			sprintf(szBuffer,"%d",dwTimmer);		
			SetWindowText(hEdit1,szBuffer);		
		}			
		ReleaseSemaphore(hSemaphore, 1, NULL);			
		return 0;			
	}				
	DWORD WINAPI ThreadProc2(LPVOID lpParameter)				
	{				
		TCHAR szBuffer[10];			
		DWORD dwTimmer=0;			
		WaitForSingleObject(hSemaphore, INFINITE);			
		while(dwTimmer<100)			
		{			
			Sleep(100);		
			memset(szBuffer,0,10);		
			GetWindowText(hEdit2,szBuffer,10);		
			sscanf( szBuffer, "%d", &dwTimmer );		
			dwTimmer++;		
			memset(szBuffer,0,10);		
			sprintf(szBuffer,"%d",dwTimmer);		
			SetWindowText(hEdit2,szBuffer);		
		}			
		ReleaseSemaphore(hSemaphore, 1, NULL);			
		return 0;			
	}				
	DWORD WINAPI ThreadProc3(LPVOID lpParameter)				
	{				
		TCHAR szBuffer[10];			
		DWORD dwTimmer=0;			
		WaitForSingleObject(hSemaphore, INFINITE);			
		while(dwTimmer<100)			
		{			
			Sleep(100);		
			memset(szBuffer,0,10);		
			GetWindowText(hEdit3,szBuffer,10);		
			sscanf( szBuffer, "%d", &dwTimmer );		
			dwTimmer++;		
			memset(szBuffer,0,10);		
			sprintf(szBuffer,"%d",dwTimmer);		
			SetWindowText(hEdit3,szBuffer);		
		}			
		ReleaseSemaphore(hSemaphore, 1, NULL);			
		return 0;			
	}				
	DWORD WINAPI ThreadBegin(LPVOID lpParameter)				
	{				
		TCHAR szBuffer[10];			
		DWORD dwMoney=0;			
					
					
		hSemaphore = CreateSemaphore(NULL,0,3,NULL);			
					
		hThread[0] = ::CreateThread(NULL, 0, ThreadProc1,NULL, 0, NULL);			
		hThread[1] = ::CreateThread(NULL, 0, ThreadProc2,NULL, 0, NULL);			
		hThread[2] = ::CreateThread(NULL, 0, ThreadProc3,NULL, 0, NULL);			
					
		//開始準備紅包			
		while(dwMoney<1000)			
		{			
			memset(szBuffer,0,10);		
			GetWindowText(hEditSet,szBuffer,10);		
			sscanf( szBuffer, "%d", &dwMoney );		
			dwMoney++;		
			memset(szBuffer,0,10);		
			sprintf(szBuffer,"%d",dwMoney);		
			SetWindowText(hEditSet,szBuffer);		
		}			
		ReleaseSemaphore(hSemaphore, 2, NULL);			
					
		::WaitForMultipleObjects(3, hThread,TRUE,INFINITE);			
		::CloseHandle(hSemaphore);			
					
		return 0;			
	}				
	BOOL CALLBACK MainDlgProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)				
	{				
		BOOL bRet = FALSE;			
					
		switch(uMsg)			
		{			
		case WM_CLOSE:			
			{		
				EndDialog(hDlg,0);	
				break;	
			}		
		case WM_INITDIALOG:			
			{		
				hEditSet = GetDlgItem(hDlg,IDC_EDIT_SET);	
				hEdit1 = GetDlgItem(hDlg,IDC_EDIT_1);	
				hEdit2 = GetDlgItem(hDlg,IDC_EDIT_2);	
				hEdit3 = GetDlgItem(hDlg,IDC_EDIT_3);	
					
				SetWindowText(hEditSet,"0");	
				SetWindowText(hEdit1,"0");	
				SetWindowText(hEdit2,"0");	
				SetWindowText(hEdit3,"0");	
					
				break;	
			}		
		case WM_COMMAND:			
					
			switch (LOWORD (wParam))		
			{		
			case IDC_BUTTON_BEGIN:		
				{	
					CreateThread(NULL, 0, ThreadBegin,NULL, 0, NULL);
					
					return TRUE;
				}	
			}		
			break ;		
		}			
					
		return bRet;			
	}				
	int APIENTRY WinMain(HINSTANCE hInstance,				
	                     HINSTANCE hPrevInstance,				
	                     LPSTR     lpCmdLine,				
	                     int       nCmdShow)				
	{				
	 	// TODO: Place code here.			
		DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG_MAIN),NULL,MainDlgProc);			
		return 0;			
	}				
	

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章