VC++ 线程同步之临界区(CriticalSection)

VC++ 线程同步之临界区(CriticalSection)

所谓临界区就是同一时刻只能有一个线程访问的代码段。处于临界区的代码通常都是需要被多个线程访问,但又只能顺序访问的。
一般就是共享的数据。用于实现顺序访问临界区的方式有多种,互斥量、信号量、事件都可以实现。

Windows临界区,在同一个线程中是可以重复进入的,但是进入的次数与离开的次数必须相等
C++互斥量则不允许同一个线程重复加锁,否则报异常。

效果几乎可以等同于c++11的mutex,可以保护一个代码段

使用方式

//创建:
CRITICAL_SECTION my_winsec;//创建windows中的临界区,类似与互斥量,使用前必须初始化

//初始化:(通常在类构造函数中初始化)
InitializeCriticalSection(&my_winsec);//初始化临界区

//临界区使用:
EnterCriticalSection(&my_winsec);//进入临界区(加锁)
myQueue.push_back(i);
LeaveCriticalSection(&my_winsec);//离开临界区(解锁)

代码示例

下面是使用Win32 API的CriticalSection实现线程同步的C++代码:

#include   
#include   

using namespace std;  

CRITICAL_SECTION g_cs;         // 全局的临界区  

DWORD WINAPI ThreadProc(LPVOID lpParam)  
{  
    EnterCriticalSection(&g_cs);  

    // 这里是需要同步的代码  
    cout << "Thread " << lpParam << " is running." << endl;  

    LeaveCriticalSection(&g_cs);  

    return 0;  
}  

int main()  
{  
    InitializeCriticalSection(&g_cs);  

    HANDLE hThread[3];  
    for (int i = 0; i < 3; i++)  
    {  
        hThread[i] = CreateThread(NULL, 0, ThreadProc, (LPVOID)i, 0, NULL);  
        if (hThread[i] == NULL)  
        {  
            cout << "Thread " << i << " failed to create." << endl;  
        }  
    }  

    WaitForMultipleObjects(3, hThread, TRUE, INFINITE);  

    DeleteCriticalSection(&g_cs);  

    return 0;  
}

在这个例子中,我们创建了一个全局的CriticalSection对象g_cs,这个对象被多个线程共享。线程执行需要同步的代码前,首先调用EnterCriticalSection函数获取临界区的访问权,执行完需要同步的代码后再调用LeaveCriticalSection函数释放临界区的访问权。这样就能确保多个线程不会同时访问临界区,从而达到线程同步的目的。

自动析构技术

Windows临界区中没有类似于C++ 11中的std::lock_guard的自动管理临界区上锁与取消锁的API,可以根据其特点手写一个:

//自动释放Windows临界区,防止忘记解锁,即实现一个Windows的lock_guard();
class CWinLock
{
public:
	CWinLock(CRITICAL_SECTION *CS)
	{
		m_CS = CS;
		EnterCriticalSection(m_CS);
	}
	~CWinLock()
	{
		LeaveCriticalSection(m_CS);
	}

private:
	CRITICAL_SECTION* m_CS;
};

怎么使用:

CRITICAL_SECTION my_winsec;//创建windows中的临界区

CWinLock cw(&my_winsec);
myQueue.push_back(i);

该文章会更新,欢迎大家批评指正。

推荐一个零声学院免费公开课程,个人觉得老师讲得不错,
分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习:
服务器课程:C++服务器

你可能感兴趣的:(Windows,C++开发,c++,windows)