关键代码段实现线程同步

关键代码段也称为临界区,工作在用户方式下,它是指一个小代码段,在代码能执行前,它必须独占对某些资源的访问权。

通常把多线程中访问同一种资源的那部分代码当做关键代码段。

 

关键代码段就好像公共电话亭一样,只有公共电话亭没有人在打电话时,其他人才有可能去打电话,如果有人打电话,其他人必须等待,当使用电话的那个人离开后,其他人才可以进去打电话。关键代码段类似这种情况,只有没有线程访问关键代码段时,其他线程才可以访问关键代码段,否则必须等待才可以进入。

 

进入关键代码段之前,首先需要初始化一个这样的关键代码段,可以调用InitializeCriticalSection函数实现。

函数声明:

void InitializeCriticalSection( 
LPCRITICAL_SECTION lpCriticalSection ); 

lpCriticalSection    Pointer to the critical section object.

该函数有一个参数,是一个指向LPCRITICAL_SECTION 结构体的指针。该函数式out类型,即作为返回值使用的。因此,在使用时,需要构造一个LPCRITICAL_SECTION 结构体类型的对象,然后将该对象的地址传递给该函数,系统自动维护该对象,我们不需要了解和访问该结构体的对象的内部成员。

 

如果想进入关键代码段,首先需要调用EnterCriticalSection函数,以获取指定的临界区对象的所有权。该函数等待指定的临界区对象的所有权,如果该所有权赋予了调用线程,则该函数就返回,否则该函数就会一直等待,从而导致线程等待。

void EnterCriticalSection( 
LPCRITICAL_SECTION lpCriticalSection ); 

 

当调用线程获得了指定的临界区对象的所有权后,该线程就进入关键代码段,对所保护的资源进行访问。

 

线程使用完所保护的资源之后,需要调用LeaveCriticalSection函数,释放指定的临界区对象的所有权,之后,其他想要获得该临界区的对象所有权的线程就可以获得该所有权,从而进入关键代码段。访问保护的资源。

void LeaveCriticalSection( 
LPCRITICAL_SECTION lpCriticalSection ); 

 

对临界区对象来说,当不再需要时,需要调用DeleteCriticalSection函数释放该对象,该函数将释放一个没有被任何线程所拥有的临界区对象的所有资源。

void DeleteCriticalSection( 
LPCRITICAL_SECTION lpCriticalSection ); 

 

利用关键代码段实现线程同步需要调用以上四个函数,以及调用步揍。

 

#include <windows.h>//调用windows API 函数
#include <iostream.h>

//关键代码段实现线程同步
int tickets=10;
CRITICAL_SECTION  CriticalSection ;	//关键代码段

//线程1函数
DWORD WINAPI Fun1Proc( LPVOID lpParameter )
{
	while( true )
	{
	
		EnterCriticalSection( &CriticalSection  );
	
		if( tickets > 0 )
		{
			Sleep(1);
			cout << "线程1卖出一张票." << tickets-- << endl;
			LeaveCriticalSection( &CriticalSection );
		}
		else
		{
			LeaveCriticalSection( &CriticalSection );
			break;
		}
	}
	return 0;
}
//线程2函数
DWORD WINAPI Fun2Proc( LPVOID lpParameter )
{
	while( true )
	{
		EnterCriticalSection( &CriticalSection );
		if( tickets > 0 )
		{
			Sleep(1);
			cout << "线程2卖出一张票." << tickets-- << endl;
			LeaveCriticalSection( &CriticalSection );
		}
		else
		{
			LeaveCriticalSection( &CriticalSection );
			break;
		}
	}
	return 0;
}



//main函数是主线程入口函数,然后可以创建其他新线程
void main()
{
	HANDLE hThread1;
	HANDLE hThread2;

	//创建两个线程
	hThread1 = CreateThread( NULL, 0, Fun1Proc, NULL, 0, NULL );
	hThread2 = CreateThread( NULL, 0, Fun2Proc, NULL, 0, NULL );
	CloseHandle( hThread1 );
	CloseHandle( hThread2 );

	InitializeCriticalSection( &CriticalSection );
	Sleep(400);
	cout << "over." << endl;
	
	DeleteCriticalSection( &CriticalSection );

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值