关键代码段实现线程同步

来源:互联网 发布:阿里云金牌合作伙伴 编辑:程序博客网 时间:2024/05/21 11:21

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

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

 

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

 

进入关键代码段之前,首先需要初始化一个这样的关键代码段,可以调用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 );}

原创粉丝点击