MFC-互斥锁和临界区

windows提供了四种多任务同步方法:

1.临界区(critical section)

2.事件(event)

3.信号量(Semaphore)

4.互斥量(Mutex)

    其中,临界区是用户对象,效率较高,但只能用于同一进程的多线程同步,其他方法是内核对象,可以用于多进程间的线程同步.本文介绍临界区和互斥量的使用方法.思路如下:

    -windows api临界区

    -windows api互斥量

    -MFC临界区类

    -MFC互斥量类

    -注意事项

1.windows api临界区

在每个访问共享资源的代码片段前,调用"进入"临界区函数,访问完成后,再调用"离开"临界区函数.

首先要,定义全局临界区变量:

CRITICAL_SECTION g_crit;

在一个函数中,初始化临界区:(只进行一次)

InitializeCriticalSection(&g_crit);

在访问全局资源前,进入临界区,代码段加入:

EnterCriticalSection(&g_crit);

则其他同样调用该函数和参数的线程,会处于等待状态.

访问完成后,离开临近区,代码段加入:

LeaveCriticalSection(&g_crit);

其他线程就可以继续执行.


2.windows api互斥量

与临界区使用方法类似,不同的是,由于是内核维护,所以无需使用全局变量的方式,而是使用互斥量句柄.

创建互斥量--等待持有资源--释放资源占有.

每个创建的互斥量名字不可相同.否则,系统会返回原有的句柄.

创建互斥量:

HANDLE h_mutex = CreateMutex(NULL, FALSE, TEXT("pbm"));

参数2表示是否立即持有资源,一般取FALSE,不立即持有.

等待持有资源:

WaitForSingleObject(h_mutex,INFINITE);

释放资源占有:

ReleaseMutex(h_mutex);


3.MFC临界区

MFC提供了类:CCriticalSection代表临界区.

增加头文件:#include "afxmt.h"

定义全局的临界区:

CCriticalSection g_criSection;

使用类的成员函数,即可实现进入临界区,离开临界区的操作:

g_criSection.Lock();
/*
 ...用户代码...
*/
g_criSection.UnLock();


4.MFC互斥量

MFC提供类:CMutex代表互斥量.

CMutex(
   BOOL bInitiallyOwn = FALSE,        //一般默认,代表不占有(非锁定)
   LPCTSTR lpszName = NULL,           //互斥体名
   LPSECURITY_ATTRIBUTES lpsaAttribute = NULL 
);
定义互斥体对象:
CMutex test_mutex(FALSE,"pbm"); 

使用成员函数,访问共享资源:

test_mutex.Lock(); 
/*
  ...用户代码...
*/ 
test_mutex.Unlock(); 


5.注意事项

    访问共享资源的代码段,如果未使用临界区或互斥量技术,即使其他代码段均使用临界区或互斥量保护共享资源,依然无法实现线程互斥.

    所以,在每个访问共享资源的代码片段,都要添加"出入锁".





猜你喜欢

转载自blog.csdn.net/csm1972385274/article/details/80207878
今日推荐