Это отвратительно? Копируемый мьютекс для защиты члена класса

0

Я пытаюсь сделать класс потоком безопасным с помощью мьютекса.

class Container
{
  private:
   vector<Foo> v;
   boost::mutex m;
  public:
   void add(Foo item)
   {
      m.lock();
      v.push_back(item);
      m.unlock();
   }
};

Проблема заключается в том, что boost::mutex не копируется, поэтому это делает Container не подлежащим копированию. Конечно, если я копирую Container новый экземпляр, по-видимому, не должен содержать тот же мьютекс, что и старый, - он может иметь новый собственный мьютекс. Я мог написать собственные конструкторы копирования для Container которые это делают, но на самом деле это сложный класс, и я не хочу этого делать. Итак, как насчет этого:

class CopyableMutex
{
private:
    boost::mutex m;
public:
    CopyableMutex() {}
    CopyableMutex(CopyableMutex&) {} //don't copy, just create a new one
    CopyableMutex& operator=(CopyableMutex&) {return *this;} //don't assign, keep it the same
    void lock() {m.lock();}
    void unlock() {m.unlock();}
};

... и затем заменить boost::mutex в Container с помощью CopyableMutex.

Это отвратительная вещь? Если нет, то я изобретаю колесо - есть ли класс библиотеки, который делает это уже?

  • 2
    Вы можете заменить «плохая идея» на «отвратительный» (грамматика fsvo), если вы чувствуете искушение указать, что весь C ++ отвратительный :)
  • 0
    Если вам нужен только этот тип в этом классе Container , просто сделайте его закрытым вложенным классом (неправильное использование невозможно). В противном случае, укажите в названии, что это не копируемый мьютекс (не выполняет CopyableMutex a; CopyableMutex b(a); assert(a == b); ), а скорее create-new-on-invoking-copy -мьютекс (это ужасное имя;)
Теги:
multithreading

1 ответ

2
Лучший ответ

Да, это отвратительно.

Правильное решение проблемы - это специальный конструктор копирования и оператор присваивания для вашего контейнера.

Если класс "слишком сложный" для написания конструктора специальных копий, а затем отделяет безопасность потока от контейнера и имеет контейнер базового класса, который не содержит мьютекс и, возможно, производный класс "поточно-безопасный контейнер", который содержит мьютекс и имеет собственный конструктор копий и назначение op, которые просто вызывают для автоматически созданных базовых классов.

  • 0
    Интересно, можете ли вы кратко сказать мне, почему это плохая идея?
  • 0
    Если ничего другого, это совершенно неожиданное поведение.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню