这不是一个惊天动地的文章,仅仅是我学到的技巧。喜欢它的原因是它不是华而不实的。
在C#中,我们没有首选采用lock去阻止来自不同的进程的同时访问。但是,在C++中,你需要明确的两部分:“EnterCriticalSection”和“LeaveCriticalSection”。有时候你进去,但是忘记离开。这里我们来关注这个问题,并使得代码更加紧凑。
代码如下所示:
// All Lock classes using this will be mutually exclusive static Section mySection; void SomeFunction() { // This block cannot be accessed simultaneously by multiple threads { Lock lock(mySection); // // any arbitrary code // } // end of locked block }
简单不?基本上这就是你要做的,去为每一个需要被锁住的模块代码去定义一个“Sectioninstance”。它通常会是一个类成员,但是也能够很方便的成为全局的。然后在模块中去包裹一部分需要被锁住的代码,然后把“Lockinstance”放在它的上方,然后传“Sectioninstance”给它就可以了。
如果你有几个模块需要被锁住,并且这些进程来自多个进程,并不是相互之间的进程,就需要创建相同数量的“sections”, 然后在每个模块里面使用它们。
以下是lock.h的内容,它包含了两个类:“Lock”和“Section”.
// Lock.h #pragma once #include <windows.h> class Lock; // Forward declaration // Class to encapsulate CRITICAL_SECTION class Section { // Actual critical section that will do the locking CRITICAL_SECTION criticalSection; public: // Constructor initializes critical section Section() { InitializeCriticalSection(&criticalSection); } // Destructor deletes critical section ~Section() { DeleteCriticalSection(&criticalSection); } private: friend Lock; // Allow Lock class to access Enter and Leave methods // Methods to enter and leave the critical section defined by the field above void Enter() { EnterCriticalSection(&criticalSection); } void Leave() { LeaveCriticalSection(&criticalSection); } }; // Class that does the locking class Lock { Section & section; // Section defined by user will be saved here public: // Constructor saves user defined critical section and enters it Lock(Section & s) : section(s) { section.Enter(); } // Destructor leaves critical section ~Lock() { section.Leave(); } };
就是这样,很简单(但是看起来很麻烦)
所以这里究竟发生了什么?熟手能明显的发现它,但是我这里会尽量解释的简单一些让新手明白。
首先,Section仅仅是隐藏了常规的“CRITICAL_SECTION”。为什么要隐藏它呢?仅仅是防止我们的代码把它弄乱。构造函数和解析函数初始化和删除“CRITICAL_SECTION”分开进行。
类“Lock”做常规的锁操作。 当我们在代码模块中创建这一类的自动变量,构造函数会被调用,然后进入一个重要的部分去定义“Section”,传值给它。离开这个模块的范围的时候会调用解析函数,解析函数回去调用“LeaveCriticalSection”。
注意到:“Section”是在“Lock”中是引用-这就阻止了前者的狗仔函数重复被调用,引起对同一个“CRITICAL_SECTION”重复初始化。
MSDN page for related APIs - Critical Section Objects.
这里只是一个光秃秃的代码去说明原理,没有异常处理。如果你需要,你自己去添加。例子编译采用的是Visual C++ 2010 Express, 其他的版本可能会有警告。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。 2KB翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。2KB项目(www.2kb.com,源码交易平台),提供担保交易、源码交易、虚拟商品、在家创业、在线创业、任务交易、网站设计、软件设计、网络兼职、站长交易、域名交易、链接买卖、网站交易、广告买卖、站长培训、建站美工等服务