我需要处理来自多个线程的数组,因此我使用CRITICAL SECTION为它提供对数据的独占访问.
这是我的模板:
#include "stdafx.h" #ifndef SHAREDVECTOR_H #define SHAREDVECTOR_H #include#include template class SharedVector { std::vector vect; CRITICAL_SECTION cs; SharedVector(const SharedVector & rhs) {} public: SharedVector(); explicit SharedVector(const CRITICAL_SECTION& CS); void PushBack(const T& value); void PopBack(); unsigned int size() const; T& operator[](int index); virtual ~SharedVector(); }; template SharedVector ::SharedVector() { InitializeCriticalSection(&cs); } template SharedVector ::SharedVector(const CRITICAL_SECTION& r): cs(r) { InitializeCriticalSection(&cs); } template void SharedVector ::PushBack(const T& value) { EnterCriticalSection(&cs); vect.push_back(value); LeaveCriticalSection(&cs); } template void SharedVector ::PopBack() { EnterCriticalSection(&cs); vect.pop_back(); LeaveCriticalSection(&cs); } template unsigned int SharedVector ::size() const { EnterCriticalSection(&cs); unsigned int result = vect.size(); LeaveCriticalSection(&cs); return result; } template T& SharedVector ::operator[](int index) { EnterCriticalSection(&cs); T result = vect[index]; LeaveCriticalSection(&cs); return result; } template SharedVector ::~SharedVector() { DeleteCriticalSection(&cs); }
虽然编译我有打电话这样的问题EnterCriticalSection(&cs)
和LeaveCriticalSection(&cs)
:
'EnterCriticalSection' : cannot convert parameter 1 from 'const CRITICAL_SECTION *' to 'LPCRITICAL_SECTION'
我不知道出了什么问题.可能你可以看到.只因为我总是以这种方式使用它而且没关系.windows.h
已经包括了
只需声明cs
为:
mutable CRITICAL_SECTION cs;
或者删除const子句 size()
输入关键部分会修改CRITICAL_SECTION
,然后再次修改它.由于进入和离开一个关键部分不会使size()
方法调用逻辑上不是const
,我会说让它声明const
,并且make cs
mutable
.这是mutable
引入的情况类型.
另外 - 看看Martin York和Joe Mucchiello的建议 - 尽可能使用RAII来处理任何需要清理的资源.这对于关键部分和指针和文件句柄一样有效.
上面的代码也不是Exception安全的.
无法保证push_back()pop_back()不会抛出.如果他们这样做,他们将永久锁定您的关键部分.你应该创建一个在构造上调用EnterCriticalSection()和在销毁时调用LeaveCriticalSection()的locker类.
这也使您的方法更容易阅读.(见下文)
class CriticalSectionLock { public: CriticalSectionLock(CRITICAL_SECTION& cs) : criticalSection(cs) { EnterCriticalSection(&criticalSection); } ~CriticalSectionLock() { LeaveCriticalSection(&criticalSection); } private: CRITICAL_SECTION& criticalSection; }; // Usage template unsigned int SharedVector::size() const { CriticalSectionLock lock(cs); return vect.size(); }
另一件你应该担心的事情.确保当您销毁对象时,您拥有所有权,并且在销毁期间没有其他人试图取得所有权.希望你的DestoryCriticalSection()能够解决这个问题.