Использование задач EnterCriticalSection

Единственный безопасный способ гарантировать, что StringBuilder подходит для сборки мусора, такой же, как и все объекты: уничтожить все ссылки на него. Это означает, что нужно явно установить его на null или позволить ему выпасть из области видимости.

Кроме того, вы не можете контролировать, когда освобождается память. Максимум, что вы можете сделать, это запросить сборку мусора, и это редко хорошая идея (не говоря уже о том, что вы просто запрашиваете, а не заказываете JVM для сбора мусора).

Другие предложенные вами варианты не гарантируют освобождение всей памяти, если вы не углубились в код и не уверены, что полностью очищаете состояние объекта. Вот почему обычно намного лучше просто обнулить всю ссылку на объект и начать все сначала, если вы хотите убедиться, что все «чисто».

6
задан Eclipse 21 December 2008 в 23:25
поделиться

6 ответов

Просто объявите cs как:

mutable CRITICAL_SECTION cs;

или иначе удалите пункт константы на size()

Ввод критического раздела изменяет CRITICAL_SECTION, и отъезд изменяет его снова. Начиная с ввода и отъезда критического раздела не делает size() вызов метода логически не -const, Я сказал бы, что отпуск это объявило const, и сделайте cs mutable. Это - тип ситуации mutable был представлен для.

Также - смотрят на предложения Martin York и Joe Mucchiello - используют RAII, когда это возможно, для контакта с любым видом ресурсов, которые должны быть очищены. Это работает точно также на критические разделы, как это делает для указателей и дескрипторов файлов.

20
ответ дан 8 December 2019 в 02:53
поделиться

Также кодом выше не является безопасное Исключение.
Нет никакой гарантии, что push_back () pop_back () не бросит. Если они сделают то они оставят Ваш критический раздел постоянно заблокированным. Необходимо создать класс блокировщика, который называет EnterCriticalSection () на конструкции и LeaveCriticalSection () на разрушении.

Также это делает Ваши методы намного легче читать. (см. ниже),

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 () заботится об этом.

7
ответ дан 8 December 2019 в 02:53
поделиться

EnterCriticalSection не берет аргумент константы. Это - ошибка компиляции, BTW, не связывающаяся ошибка...

Кроме того, Вы уверенный, что Вы хотите передать в критическом разделе в Ваш ctor, и затем иметь ctor работают InitializeCriticalSection звонить? Если бы Вы хотите совместно использовать свой критический раздел, я предполагаю, что Вы инициализировали бы его сначала и затем раздали бы его.

1
ответ дан 8 December 2019 в 02:53
поделиться

Я предпочитаю использовать отдельный объект Приобретения по Вашему коду. Ваш код, если хрупкий, когда исключение происходит между вызовами Введения и Отпуска:

class CS_Acquire {
    CRITICAL_SECTION &cs;
public:
    CS_Acquire(CRITICAL_SECTION& _cs) : cs(_cs) { EnterCriticalSection(cs); }
    ~CS_Acquire() { LeaveCriticalSection(cs); }
};

Затем в Ваших методах класса Вы кодировали бы его как:

template <typename T>
void SharedVector::PushBack(const T& value) {
   CS_Acquire acquire(&cs);
   vect.push_back(value);
}
3
ответ дан 8 December 2019 в 02:53
поделиться

таким образом это - что-то не так с правами доступа. Я сделал размер () неконстантой метода, и теперь это в порядке.

0
ответ дан 8 December 2019 в 02:53
поделиться

Я вижу, что Вы объявляете пустого конструктора копии:

SharedVector(const SharedVector& rhs) {}

Поскольку я уверен, что Вы знаете, эта функция ничего не делает, и она также уезжает cs неинициализированный. Поскольку Ваш класс содержит экземпляр a CRITICAL_SECTION, несомненно, необходимо будет запретить конструктору копии и вызовам оператора присваивания, если Вы не собираетесь реализовать их полностью. Можно сделать это путем размещения следующих объявлений в private раздел Вашего класса:

SharedVector(const SharedVector &);
SharedVector &operator=(const SharedVector &);

Это препятствует тому, чтобы компилятор автоматически генерировал неверные версии этих методов и также препятствует тому, чтобы Вы назвали их в другом коде, который Вы пишете (потому что это только объявления, но не определения с {} блоки кода).

Кроме того, как Arnout упомянул, конструктор, который берет a CRITICAL_SECTION& аргумент кажется неправильным. То, что делает Ваша реализация, скопировать переданный - в критическом разделе к cs (который не является допустимой вещью сделать с a CRITICAL_SECTION), затем звонит InitializeCriticalSection(&cs) который перезаписывает копию, Вы просто сделали и создаете новый критический раздел. Вызывающей стороне, которая передала в критическом разделе, это, кажется, делает неправильную вещь путем эффективного игнорирования того независимо от того, что было передано в.

1
ответ дан 8 December 2019 в 02:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: