您的位置:首页 > 其它

线程同步——用户模式下线程同步——关键段实现线程同步

2014-08-16 11:00 393 查看
//2.使用关键段实现线程同步
使用时必须有以下几个步骤
//(1)必须先定义 CRITICAL_SECTION 结构
CRITICAL_SECTION  g_cs;
//(2)初始化关键段 CRITICAL_SECTION
InitializeCriticalSection(&g_cs);
//(3)在线程中调用
DWORD WINAPI ThreadFunOne(PVOID pvParam)
{
EnterCriticalSection(&g_cs)  ;

//共享的资源应该放在EnterCriticalSection和EnterCriticalSection函数之间

EnterCriticalSection(&g_cs);
return 0;
}
//(4)清理CRITICAL_SECTION结构,必须确保已经没有资源使用此关键段,否则会出现不可预料的结果
DeleteCriticalSection(&g_cs);
//关于
VOID EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection ) ;
1)如果没有线程正在访问资源,那么EnterCriticalSection立刻更新成员变量,以表示调用线程
已经获准的对资源的访问,并立即返回,这样线程可以继续执行代码(访问资源)。
2)如果成员变量表示调用线程已经获准访问资源,那么EnterCriticalSection更新变量,以表示调用线程被准获访问次数,
并立即返回。这种情况很少,只有当线程调用LeaveCriticalSection 之前连续调用EnterCriticalSection两次及以上才会发生。
3)如果成员变量表示有一个(调用线程之外的其他)线程已经获准访问资源,那么EnterCriticalSection会使用
一组内核对象,把线程切换为等待状态,等待不会浪费CPU时间,这就完美了。
一句话概括就是:调用 EnterCriticalSection 一个线处理资源,其他线程变为等待。

VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection )
系统会自动更新 CRITICAL_SECTION 的成员变量并将等待的线程,切换为可调度状态。

VOID TryEnterCriticalSection(  LPCRITICAL_SECTION lpCriticalSection ) ;
此函数可以代替 EnterCriticalSection 函数,但是:
此函数从来不会让调用线程等待。它可以通过返回值查看,调用线程是否获准访问资源,
如果其它线程正在访问资源,则返回 FALSE ,否则,返回 TRUE 。

#include "windows.h"
#include "iostream"
using namespace std;
long g_x = 0 ;
//(1)必须先定义 CRITICAL_SECTION 结构
CRITICAL_SECTION  g_cs;

//定义线程函数1
DWORD WINAPI ThreadFunOne(PVOID pvParam) ;

//定义线程函数2
DWORD WINAPI ThreadFunTwo(PVOID pvParam);

int main()
{

//(2)初始化关键段 CRITICAL_SECTION
InitializeCriticalSection(&g_cs);

//创建线程1
HANDLE hThreadOne = CreateThread(NULL,0,ThreadFunOne,0,0,NULL);
CloseHandle(hThreadOne);

//创建线程2
HANDLE hThreadTwo = CreateThread(NULL,0,ThreadFunTwo,0,0,NULL);
CloseHandle(hThreadTwo);

//让主线程先挂起,确保其它线程执行完成
Sleep(1000);
cout<<g_x<<endl;

//(4)清理CRITICAL_SECTION结构,必须确保已经没有资源使用此关键段,否则会出现不可预料的结果
DeleteCriticalSection(&g_cs);
return 0 ;
}

DWORD WINAPI ThreadFunOne(PVOID pvParam)
{
EnterCriticalSection(&g_cs)  ;

//共享的资源应该放在EnterCriticalSection和EnterCriticalSection函数之间
g_x++;

EnterCriticalSection(&g_cs);
return 0;
}

DWORD WINAPI ThreadFunTwo(PVOID pvParam)
{
EnterCriticalSection(&g_cs)  ;

//共享的资源应该放在EnterCriticalSection和EnterCriticalSection函数之间
g_x++;

LeaveCriticalSection(&g_cs);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: