Может ли объект критической секции храниться в std :: vector? - PullRequest
3 голосов
/ 11 июня 2019

Согласно документации , критический объект secion не может быть скопирован или перемещен.

Означает ли это, что его нельзя безопасно сохранить в коллекции стиля std::vector в качестве экземпляра?

1 Ответ

1 голос
/ 11 июня 2019

Корректное; объект CRITICAL_SECTION не следует копировать / перемещать, поскольку он может перестать работать (например, возможно, он содержит указатели на себя).

Один из подходов - хранить вектор умных указателей, например, (Код C ++ 17):

#include <windows.h>
#include <memory>
#include <vector>

using CS_ptr = std::unique_ptr<CRITICAL_SECTION, decltype(&DeleteCriticalSection)>;

CS_ptr make_CriticalSection(void)
{
    CS_ptr p(new CRITICAL_SECTION, DeleteCriticalSection);
    InitializeCriticalSection(p.get());
    return p;
}

int main()
{
    std::vector<CS_ptr> vec;
    vec.push_back( make_CriticalSection() );    
}

Подумайте об использовании std::recursive_mutex, который является заменой для CRITICAL SECTION (и, возможно, просто включает его в реализацию Windows), и выполняет правильную инициализацию и выпуск в своем деструкторе.

Стандартные мьютексы также не подлежат копированию, поэтому в этом случае вы должны использовать std::unique_ptr<std::recursive_mutex>, если вы хотите их вектор.

Как обсуждалось здесь , также подумайте, действительно ли вы хотите std::mutex вместо рекурсивного мьютекса.

ПРИМЕЧАНИЕ: Windows Mutex является межпроцессным объектом; std::mutex и друзья соответствуют CRITICAL_SECTION.


Я бы также предложил пересмотреть необходимость вектора мьютексов; может быть лучшее решение для всего, что вы пытаетесь сделать.

...