che*_*r89 6 c++ winapi critical-section
我需要处理来自多个线程的数组,因此我使用CRITICAL SECTION为它提供对数据的独占访问.
这是我的模板:
#include "stdafx.h"
#ifndef SHAREDVECTOR_H
#define SHAREDVECTOR_H
#include <vector>
#include <windows.h>
template<class T>
class SharedVector {
std::vector<T> vect;
CRITICAL_SECTION cs;
SharedVector(const SharedVector<T>& 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<class T>
SharedVector<T>::SharedVector() {
InitializeCriticalSection(&cs);
}
template<class T>
SharedVector<T>::SharedVector(const CRITICAL_SECTION& r): cs(r) {
InitializeCriticalSection(&cs);
}
template<class T>
void SharedVector<T>::PushBack(const T& value) {
EnterCriticalSection(&cs);
vect.push_back(value);
LeaveCriticalSection(&cs);
}
template<class T>
void SharedVector<T>::PopBack() {
EnterCriticalSection(&cs);
vect.pop_back();
LeaveCriticalSection(&cs);
}
template<class T>
unsigned int SharedVector<T>::size() const {
EnterCriticalSection(&cs);
unsigned int result = vect.size();
LeaveCriticalSection(&cs);
return result;
}
template<class T>
T& SharedVector<T>::operator[](int index) {
EnterCriticalSection(&cs);
T result = vect[index];
LeaveCriticalSection(&cs);
return result;
}
template<class T>
SharedVector<T>::~SharedVector() {
DeleteCriticalSection(&cs);
}
Run Code Online (Sandbox Code Playgroud)
虽然编译我有打电话这样的问题EnterCriticalSection(&cs)和LeaveCriticalSection(&cs):
'EnterCriticalSection' : cannot convert parameter 1 from 'const CRITICAL_SECTION *' to 'LPCRITICAL_SECTION'
我不知道出了什么问题.可能你可以看到.只因为我总是以这种方式使用它而且没关系.windows.h已经包括了
Ecl*_*pse 20
只需声明cs为:
mutable CRITICAL_SECTION cs;
Run Code Online (Sandbox Code Playgroud)
或者删除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();
}
Run Code Online (Sandbox Code Playgroud)
另一件你应该担心的事情.确保当您销毁对象时,您拥有所有权,并且在销毁期间没有其他人试图取得所有权.希望你的DestoryCriticalSection()能够解决这个问题.