基于visual c++之windows核心编程代码分析(12)使用信号量同步线程

我们编写多线程应用程序的时候,经常需要进行线程同步协作,我们来实践一下用信号量同步线程。请见代码实现与注释分析,

/* 头文件 */
#include <windows.h>
#include <stdio.h>
/* 常量定义 */
#define NUMTHREADS	4 
/* 全局变量 */
HANDLE hSemaphore;
/* 函数声明 */
void UseSemaphore(void);
DWORD WINAPI SemaphoreThread(LPVOID lpParam);

/*************************************
* int main(void)
* 功能	演示
*
* 参数	未使用
**************************************/
int main()
{
	 UseSemaphore() ;
}
/*************************************
* DWORD WaitForAllThread(HANDLE hThread[], DWORD dwNumThread)
* 功能	等待指定的线程都结束
*
* 参数	HANDLE hThread[]	需要等待结束的线程句柄数组
*		DWORD dwNumThread	线程句柄数组的大小
**************************************/
DWORD WaitForAllThread(HANDLE hThread[], DWORD dwNumThread)
{
	// 等待所有线程结束
	DWORD dwWaitResult = WaitForMultipleObjects(
		dwNumThread,
		hThread,				// 线程句柄作为等待对象
		TRUE,
		INFINITE);
	switch (dwWaitResult) 
		{
		case WAIT_OBJECT_0: 
			printf("\nAll thread exit\n"); 
			break; 
		default: 
			printf("\nWait error: %u", GetLastError()); 
		}
	return 0;

}

/*************************************
* void UseSemaphore(void) 
* 功能	演示UseSemaphore的使用方法
*
* 参数	未使用
**************************************/
void UseSemaphore(void) 
{
	HANDLE hThread[NUMTHREADS];
	INT i;
	LONG lMax;
	CHAR cMax;
	// 打印信息获取输入
	printf("将创建%d个进程,获得信号量的进程可以向屏幕打印。\n"
		"请输入信号量的最大计数1~%d:",NUMTHREADS,NUMTHREADS);	
	// 获得输入的字符
	cMax = getch();
	printf("%c\n",cMax);
	// 将字符转换为数字
	lMax = cMax & 0xF;
	if(lMax<0 || lMax>NUMTHREADS)
	{
		printf("请输入1-%d",NUMTHREADS);
	}
	// 创建信号量
	hSemaphore = CreateSemaphore( 
		NULL,   // 默认安全属性
		lMax,   // 初始化计数器,用户输入
		lMax,   // 最大计数,用户输入
		NULL);  // 未命名
	if (hSemaphore == NULL) 
	{
		printf("CreateSemaphore error: %d\n", GetLastError());
	}
	// 创建多个线程 访问共享资源
	for(i = 0; i < NUMTHREADS; i++) 
	{		
		hThread[i] = CreateThread(NULL, 0, 
			SemaphoreThread, 
			&i,			// 进程序号作为参数
			0, NULL); 
		if (hThread[i] == NULL) 
		{
			printf("CreateThread failed (%d)\n", GetLastError());
			return;
		}
	}
	// 等待所有线程都执行完成并退出
	WaitForAllThread(hThread,NUMTHREADS);
}

/*************************************
* DWORD WINAPI SemaphoreThread(LPVOID lpParam) 
* 功能	线程函数,读共享内存
*
* 参数	未使用
**************************************/
DWORD WINAPI SemaphoreThread(LPVOID lpParam) 
{
	DWORD dwWaitResult;
	BYTE lpRead[16];
	//DWORD i = *(LPWORD)lpParam;		// 线程的编号
	DWORD dwPreviousCount;

	DWORD j = 0;
	// 每个线程都将访问3次受限资源
	for(; j<3; j++)
	{		
		// 线程可以在此进行一些操作
		// 以暂停随机长的时间模拟真实情况
		Sleep(rand()%1000);
		// 等待信号量
		dwWaitResult = WaitForSingleObject( 
			hSemaphore,      // 信号量句柄
			INFINITE);		 // 无限等待
		switch (dwWaitResult) 
		{
		case WAIT_OBJECT_0: 
			printf("\nProcess %d Gets Semaphore",GetCurrentThreadId());
			break; 
		default: 
			printf("\nprocess %u Wait error: %u",GetCurrentThreadId(), GetLastError()); 
		}
		// 获得信息量后访问受限资源
		// 以等待随机长时间模块真实情况
		Sleep(rand()%1000);
		// 释放信号量
		if (!ReleaseSemaphore( 
			hSemaphore,				// 信号量句柄
			1,						// 释放后计数器减1 
			&dwPreviousCount) )		// 获得计数
		{
			printf("\nprocess %u ReleaseSemaphore error: %d", GetCurrentThreadId(), GetLastError());
		}
		else
		{
			printf("\nProcess %u release Semaphore, previous count is %u",
				GetCurrentThreadId(), dwPreviousCount);
		}
	}

	return 1;
}


 

 

你可能感兴趣的:(基于visual c++之windows核心编程代码分析(12)使用信号量同步线程)