2016-07-12 2 views
2

[Я не нашел удовлетворительного ответа на это, поэтому задал вопрос.]Должен ли класс оболочки для объекта, защищенного потоком, быть потокобезопасным?

Предположим, что у меня есть потокобезопасный класс C++ «ThreadSafeClass». Теперь я написал обертку над ней «MyWrapper». В MyWrapper нет другого члена данных. У меня есть несколько сомнений здесь:

  1. Связаны ли отдельные методы этого класса-оболочки с помощью мьютекса, чтобы сделать их потокобезопасными? Или можно с уверенностью предположить, что, поскольку базовый объект является потокобезопасным, поэтому нет необходимости?
  2. Если ответ на < 1> выше нет (в обертке нет мьютекса), то рассмотрим это: мы не защищаем класс-оболочку с помощью любого мьютекса, предполагая, что доступ к единственному базовому объекту всегда будет потокобезопасным. Теперь предположим, что 1 поток находится в деструкторе объекта-обертки, а другой поток обращается к его функции-члену (при условии, что класс-оболочка не имеет никакого мьютекса, чтобы избежать этой ситуации). Возможно ли, что объект, защищенный потоком, был уничтожен одним потоком, а затем другой поток пытается получить к нему доступ? Я знаю, это звучит немного странно и, скорее всего, я чего-то не хватает, но это зависит от ответа на вопрос < 1> выше.

    class MyWrapper { 
    private: 
        ThreadSafeClass _ts_obj; 
    public: 
        void foo() 
        { 
         _ts_obj.do_something(); 
        } 
    }; 
    
+0

В этом случае вам не нужен дополнительный «мьютекс». – Arunmu

+0

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

+1

Я думаю, вам нужно определить, что вы подразумеваете под термином «потокобезопасный объект». – Galik

ответ

3
  1. Нет, в данном случае вы не должны защитить свой класс-оболочку с дополнительным мьютекса

  2. Когда несколько потоков используют один и тот же объект, вы должны быть очень осторожны, чтобы управляйте временем жизни объекта, так что один поток не может уничтожить объект, пока он доступен другим. Самый простой способ - использовать в потоках shared_ptr<Wrapper> интеллектуальный указатель для доступа к данным. Это потокобезопасная ссылка, подсчитывающая интеллектуальный указатель, который уничтожит объект, если он не ссылается ни на какой поток. не

1
  1. Нет вам не нужен дополнительный слой мьютекса.
  2. Если вы делите объект между двумя потоками, вам нужно передать объект в качестве ссылки/указателя. В этом случае деструктор потока будет очищать только ссылку/указатель, но собственный объект удаления, лежащий в основе, поэтому все в порядке. Если вы будете передавать объект как копию, все будет хорошо.

Редактировать: Конечно, если вы принудительно удаляете объект, лежащий под указателем, у вас будет ошибка сегментации.

Смежные вопросы