Создание нескольких lock_guards в функции - PullRequest
1 голос
/ 27 января 2020

У меня есть класс, содержащий вектор, полный указателей на объекты std :: mutex (число зависит от действий пользователя) и функцию-член. В этой функции я хочу выполнить некоторые операции, но мне нужно вызвать все объекты мьютекса (используя std :: lock_guard) перед выполнением этих операций, чтобы избежать конфликтов потоков. Моя первая идея состояла в том, чтобы сделать это, используя for-l oop:

for(int i = 0; i < number_of_mutex; i++)
    std::lock_guard<std::mutex> mut[i];

Конечно, это не сработало, потому что lock_guards go выходит за рамки после каждой итерации. Итак, я решил создать внешний вектор для хранения lock_guards:

std::vector<std::lock_guard<std::mutex>> mut_set;
for(int i = 0; i < number_of_mutex; i++)
    mut_set.push_back(std::lock_guard<std::mutex>(mut[i]));

Моя программа сейчас компилируется, но я подозреваю, что это может быть неправильно. Консоль говорит «ошибка: использование удаленной функции»:

/home/main.cpp:2162:74:   required from here
/usr/include/c++/7/ext/new_allocator.h:136:4: error: use of deleted function ‘std::lock_guard<_Mutex>::lock_guard(const std::lock_guard<_Mutex>&) [with _Mutex = std::mutex]’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }

Обратите внимание, что lock_guards не подлежат копированию. Как правильно решить эту ситуацию?

1 Ответ

0 голосов
/ 27 января 2020

Класс std::lock_guard по понятным причинам не является ни копируемым, ни перемещаемым, поскольку обычно вы хотите использовать его для блокировки области. Следовательно, было бы плохо, если бы вы могли как-то заставить его покинуть область видимости (что произошло бы, передав его в вектор). Этого не было, так как std::vector требуется, чтобы его тип элемента был перемещаемым или копируемым (чтобы он мог перераспределять / изменять размер и т. Д. c.)

Вместо этого можно использовать std::unique_lock . Но будьте осторожны, чтобы ничего плохого не случилось, когда поток уже владеет мьютексом (см. Страницу с его конструкторами).

Другая возможность, как уже сказал Сэм, - добавить еще один уровень косвенности и управлять lock_guards с помощью некоторого умного указателя (unique_ptr также должен работать, и я предпочитаю его), который хранится в векторе.

Но я согласен с тем, что сказал Сэм: переосмыслите свой дизайн.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...