关键段 互斥量 以及信号量

关键段(主要是用户模式下的线程同步,但是竞争激烈的情况下会进入内核态)

一般是EnterCriticalSection和LeaveCriticalScetion配对使用,需要先创建一个CRITICAL_SECTION结构。

下面的函数用来进行初始化

void InitializerCriticalSection(PCRITICAL_SECTION pcs);

当线程不在需要访问共享资源的时候,应该调用下面的函数来清理结构

void deleteCriticalSection(PCRITICAL_SECTION pcs);

TryEnterCriticalSection从来不会让调用线程进入等待状态,他会通过返回值来表示调用线程是否获准访问资源,因此如果TryEnterCriticalSection发现资源正在被其他线程访问,那么它会返回false。每一个返回true的TryEnterCriticalSection调用必须有一个对应的LeaveCriticalSection。

互斥量

要使用互斥量,进程必须先调用CreateMutexl来插件创建一个互斥量

HANDLE CreateMutex(    
    PSECURITY_ATTRIBUTES psa,    
    BOOL bInitialOwner,    
    PCTSTR pszName);    

 bInitialOwner用来控制互斥量的初始状态。如果传入false,那么表示互斥量不属于任何线程。

线程ID和递归计数都为0。此时互斥量处于触发状态。如果为true,互斥量的线程ID将被设为主调线程的线程ID,递归计数被设为1。

OpenMutex来打开一个已存在的互斥量。

HANDLE OpenMutex(    
    DWORD dwDesiredAccess,    
    BOOL bInheritHandle,    
    PCTSTR pszName);    

使用WaitForSingleObject和ReleaseMutex配合使用,不需要的时候调用closehandle来释放该句柄

信号量

与其他所有内核对象相同,它们也包含一个使用计数,但是它们还包括另外两个32bit值,一个最大资源计数和一个当前资源计数。最大资源计数表示信号量可以控制的最大资源数量,当前资源计数表示信号量当前可用资源的数量。

信号量的规则如下:

1.如果当前资源计数大于0,那么信号量处于触发状态

2.如果当前资源计数等于0,那么信号量处于未触发状态

3.系统绝对不会让当前资源计数变为负数

4.当前资源计数绝对不会大于最大资源计数

创建信号量内核对象:

HANDLE CreateSomaphore(    
    PSECURITY_ATTRIBUTE psa,    
    LONG lInitialCount,    
    LONG lMaximuCount,    
    PCTSTR pszName);    
lMaximumCount告诉系统应用程序能够处理的资源最大数量。
 lInitialCount表示这些资源一开始有多少可供使用。

任何进程都可以调用OpenSemaphore来得到一个已经存在的信号量的句柄

HANDLE OpenSemaphore(    
    DWORD dwDesiredAccess,    
    BOOL hInheritHandle,    
    PCTSTR pszName);    
线程通过调用ReleaseSemaphore来递增信号量的当前资源计数。
// 信号量对象句柄    
HANDLE hSemaphore;    
UINT ThreadProc15(LPVOID pParam)    
{     
 // 试图进入信号量关口    
 WaitForSingleObject(hSemaphore, INFINITE);    
 // 线程任务处理    
 AfxMessageBox("线程一正在执行!");    
 // 释放信号量计数    
 ReleaseSemaphore(hSemaphore, 1, NULL);    
 return 0;    
}    
UINT ThreadProc16(LPVOID pParam)    
{     
 // 试图进入信号量关口    
 WaitForSingleObject(hSemaphore, INFINITE);    
 // 线程任务处理    
 AfxMessageBox("线程二正在执行!");    
 // 释放信号量计数    
 ReleaseSemaphore(hSemaphore, 1, NULL);    
 return 0;    
}    
UINT ThreadProc17(LPVOID pParam)    
{     
 // 试图进入信号量关口    
 WaitForSingleObject(hSemaphore, INFINITE);    
 // 线程任务处理    
 AfxMessageBox("线程三正在执行!");    
 // 释放信号量计数    
 ReleaseSemaphore(hSemaphore, 1, NULL);    
 return 0;    
}    
……    
void CSample08View::OnSemaphore()     
{    
 // 创建信号量对象    
 hSemaphore = CreateSemaphore(NULL, 2, 2, NULL);    
 // 开启线程    
 AfxBeginThread(ThreadProc15, NULL);    
 AfxBeginThread(ThreadProc16, NULL);    
 AfxBeginThread(ThreadProc17, NULL);    
}   




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值