现在的位置: 首页 > 综合 > 正文

互斥对象、事件对象、关键代码段

2013年08月10日 ⁄ 综合 ⁄ 共 3215字 ⁄ 字号 评论关闭

最近复习了一下多线程的知识

作用差不多,侧重点不一样

临界区:  共享资源
互斥对象  线程间的同步
事件对象:一般用在比较复杂的地方,能够传递一些信息

下面是互斥对象、事件对象和关键代码段的比较:

1互斥对象

#include <iostream>
#include <windows.h>
using namespace std;

// 声明两个线程函数
DWORD WINAPI ThreadProc1(
						LPVOID lpParameter   // thread data
						);

DWORD WINAPI ThreadProc2(
						LPVOID lpParameter   // thread data
						);

// 全局票数
int gTicket = 100;

// 互斥对象
HANDLE hMutex;

int main()
{
	// 创建两个线程句柄
	HANDLE hThread1 = CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
	HANDLE hThread2 = CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);

	// 创建互斥对象
	hMutex = CreateMutex(NULL, false, NULL);

	// 关闭两个线程句柄
	CloseHandle(hThread1);
	CloseHandle(hThread2);

	// 主线程睡4秒,方便两个线程函数能够获取CPU时间片
	Sleep(4000);

	system("pause");
	return 0;
}

// 定义两个线程函数
DWORD WINAPI ThreadProc1(LPVOID lpParameter )
{
	while(true)
	{
		WaitForSingleObject(hMutex, INFINITE);
		if(gTicket > 0)
		{
			cout<<"thread1 sell ticket "<<gTicket--<<endl;
		}
		else
		{
			break;
		}
		ReleaseMutex(hMutex);
	}
	return 0;
}

DWORD WINAPI ThreadProc2(LPVOID lpParameter )
{
	while(true)
	{
		WaitForSingleObject(hMutex, INFINITE);
		if(gTicket > 0)
		{
			cout<<"thread2 sell ticket "<<gTicket--<<endl;
		}
		else
		{
			break;
		}
		ReleaseMutex(hMutex);
	}
	return 0;
}


2事件对象

#include <Windows.h>
#include <iostream>
using namespace std;

// 声明两个线程函数
DWORD WINAPI ThreadProc1(
						 LPVOID lpParameter   // thread data
						 );

DWORD WINAPI ThreadProc2(
						 LPVOID lpParameter   // thread data
						 );

// 全局变量
int gTicket = 100;

// 事件对象
HANDLE hEvent;

int main()
{
	// 创建两个线程句柄
	HANDLE hThread1 = CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
	HANDLE hThread2 = CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);

	// 创建时间对象
	hEvent = CreateEvent(NULL, false, true, NULL);

	// 关闭两个线程句柄
	CloseHandle(hThread1);
	CloseHandle(hThread2);

	// 主线程睡4秒,让别的线程函数有机会获得CPU时间片
	Sleep(4000);


	system("pause");
	return 0;
}


// 定义两个线程函数
DWORD WINAPI ThreadProc1(LPVOID lpParameter )
{
	while(true)
	{
		WaitForSingleObject(hEvent, INFINITE);		
		if(gTicket > 0)
		{
			cout<<"thread1 sell ticket "<<gTicket--<<endl;
		}
		else
		{
			break;
		}
		SetEvent(hEvent);
	}
	return 0;
}

DWORD WINAPI ThreadProc2(LPVOID lpParameter )
{
	while(true)
	{
		WaitForSingleObject(hEvent, INFINITE);
		if(gTicket > 0)
		{
			cout<<"thread2 sell ticket "<<gTicket--<<endl;
		}
		else
		{
			break;
		}
		SetEvent(hEvent);
	}
	return 0;
}

3关键代码段

#include <iostream>
#include <windows.h>
using namespace std;

// 声明两个线程函数
DWORD WINAPI ThreadProc1(
						 LPVOID lpParameter   // thread data
						 );

DWORD WINAPI ThreadProc2(
						 LPVOID lpParameter   // thread data
						 );

// 全局票数
int gTicket = 100;

// 关键代码段
CRITICAL_SECTION gSection;


int main()
{

	// 初始化关键代码段,必须先于线程的创建
	InitializeCriticalSection(&gSection);

	// 创建两个线程句柄
	HANDLE hThread1 = CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
	HANDLE hThread2 = CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);

	// 关闭两个线程句柄
	CloseHandle(hThread1);
	CloseHandle(hThread2);

	// 主线程sleep 4秒
	Sleep(4000);
	
	// 删除关键代码段
	DeleteCriticalSection(&gSection);

	system("pause");
	return 0;
}

// 定义两个线程函数
DWORD WINAPI ThreadProc1(LPVOID lpParameter )
{
	while(true)
	{
		EnterCriticalSection(&gSection);							// 进入关键代码段
		if(gTicket > 0)
		{
			cout<<"thread1 sell ticket "<<gTicket--<<endl;
		}
		else
		{
			break;
		}
		LeaveCriticalSection(&gSection);							// 离开关键代码段
	}
	return 0;
}

DWORD WINAPI ThreadProc2(LPVOID lpParameter )
{
	while(true)
	{
		EnterCriticalSection(&gSection);							// 进入关键代码段
		if(gTicket > 0)
		{
			cout<<"thread2 sell ticket "<<gTicket--<<endl;
		}
		else
		{
			break;
		}
		LeaveCriticalSection(&gSection);							// 离开关键代码段
	}
	return 0;
}

程序运行的结果,相信大家都已经很清楚了,但是,前面两个内核对象(互斥对象、事件对象)的结果有点出乎意料

以事件对象为例。用断点调试,竟然发现了这样的问题。线程1的函数获取互斥对象的拥有权(并未释放拥有权),接着切换CPU时间片,进入到了线程2函数的WaitForSingleObject,然后调用了线程2函数的 cout<<"thread2
sell ticket "<<gTicket--<<endl;,这是怎么一回事呢,线程1函数还未释放拥有权,线程2函数怎么还能运行的? 

使用互斥对象,显示的结果有时候会是这样。百思不得其解。


希望大侠能点明一下在下。给点意见。


抱歉!评论已关闭.