[源码分享]Windows下的半自动线程锁

写在前面的话:开始写一套网络库,打算先用IOCP吧,Asio毕竟还在学习阶段,定义名字为FreeNet,会慢慢放出来代码的,希望大家持续关注,并互相交流。

关于IOCP的网络库,里面必不可少的肯定会用到多线程,所以轻量级的线程锁还是需要的,所以简单写了一个半自动的线程锁,所谓半自动,就是要显式的调用加锁,但是不必手动释放该锁。以前学的基础多线程中的都是显式的加锁,显式的解锁,比较繁琐。我们这里只是简单的封装了下而已。

Locker.h

/************************************************************************ 

	FileName:Locker.h
	Author	:eliteYang
	EMail	:elite_yang[at]163.com
	Copyright (C) http://www.cppfans.org
	This file is a part of FreeNet, provide a semi-automatic thread lock.

************************************************************************/
#pragma once

#include <Windows.h>

class CLocker
{
public:
	CLocker();
	~CLocker();

	void Lock();
	void UnLock();

private:
	CRITICAL_SECTION m_access;
};

//////////////////////////////////////////////////////////////////////////

class CAutoLocker
{
public:
	CAutoLocker( CLocker* pLocker );
	~CAutoLocker();
private:
	CLocker* m_pLocker;
};

这里我们用到的是临界区来加锁。

Locker.cpp

#include "Locker.h"

CLocker::CLocker()
{
	::InitializeCriticalSection(&m_access);
}

CLocker::~CLocker()
{
	::DeleteCriticalSection(&m_access);
}

void CLocker::Lock()
{
	::EnterCriticalSection(&m_access);
}

void CLocker::UnLock()
{
	::LeaveCriticalSection(&m_access);
}

CAutoLocker::CAutoLocker(CLocker* pLocker)
{
	m_pLocker = pLocker;
	if (m_pLocker)
	{
		m_pLocker->Lock();
	}
}

CAutoLocker::~CAutoLocker()
{
	if (m_pLocker)
	{
		m_pLocker->UnLock();
	}
}

这样的锁,我们在调用的时候定义一个锁对象,然后对其加锁,然后在跳出大括号的时候因为析构所以会自动解锁。

 

简单的使用例子:(注意:本例中的赋值操作是原子操作,不需要加锁的,但是只是展示如何使用的,所以就这样写了,大家千万不要多此一举啊)

#include "stdafx.h"
#include "Locker.h"

CLocker m_lock;

int _tmain(int argc, _TCHAR* argv[])
{
	CAutoLocker m_autoLocker(&m_lock);
	{
		int a = 0;
	}
	return 0;
}
  1. rangerlee说道:

    貌似Linux没有临界区这种锁,pthread只有mutex,配合条件变量很好用,条件变量这种东西可惜Windows下没有,不过boost封装了。

    1. eliteYang说道:

      所以说下面留言的这个人是广告,x

  2. happem说道:

    Windows和Linux 一样,Windows系列是完全的多任务操作系统。它们支持同样的用户接口、网络和安全性。Windows和Linux的工作方式还是存在一些根本的区别,扩展阅读:http://www.lirenedu.org/index.php?ack=xinwen&id=1205

    1. eliteYang说道:

      至少linux下进入临界区不是这样写吧。

发表评论

电子邮件地址不会被公开。必填项已用 * 标注