当前位置:  开发笔记 > 编程语言 > 正文

使用EnterCriticalSection的问题

如何解决《使用EnterCriticalSection的问题》经验,为你挑选了2个好方法。

我需要处理来自多个线程的数组,因此我使用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已经包括了



1> Eclipse..:

只需声明cs为:

mutable CRITICAL_SECTION cs;

或者删除const子句 size()

输入关键部分会修改CRITICAL_SECTION,然后再次修改它.由于进入和离开一个关键部分不会使size()方法调用逻辑上不是const,我会说让它声明const,并且make cs mutable.这是mutable引入的情况类型.

另外 - 看看Martin York和Joe Mucchiello的建议 - 尽可能使用RAII来处理任何需要清理的资源.这对于关键部分和指针和文件句柄一样有效.



2> Martin York..:

上面的代码也不是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()能够解决这个问题.

推荐阅读
依然-狠幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有