Поток безопасности и `const`

Как const(указатели, ссылки и функции-члены) помогают с безопасностью потоков в C ++?

12.12.2008 09:01:49
Это не. Тот факт, что ссылка на переменную является константой, не означает, что нет неконстантных ссылок на эту переменную.
Chris Becke 25.05.2016 13:07:53
@ChrisBecke По общему признанию, этот stackoverflow.com/questions/14127379/… гораздо лучший вопрос, заданный с большим вниманием. Я думаю, что ответы там показывают, что бойка «это не так» недостаточно.
James Hopkin 31.05.2016 10:23:24
6 ОТВЕТОВ
РЕШЕНИЕ

Основная проблема с несколькими потоками - изменчивость. const ограничивает это, но поскольку вы можете отбросить это, оно не является надежным.

6
12.12.2008 09:06:39
Правда, но вам нужно проделать дополнительную работу, чтобы выстрелить себе в ногу.
Toon Krijthe 12.12.2008 09:08:48
Я согласен, и как программист C # в эти дни я определенно скучаю по const &
Brian Rasmussen 12.12.2008 09:40:12
Ни один кодекс не защищен от ошибок, но вы должны защищаться от Мерфи, а не от Макиавелли.
Gorpik 12.12.2008 10:37:21
Вам даже не нужно выбрасывать это. Единственное, что подразумевает const, это то, что ВАМ не разрешено изменять это, НЕ то, что никто другой не может. Может быть много ранее существующих неконстантных ссылок на переменную.
Chris Becke 25.05.2016 13:10:39

Любые неизменяемые (то есть неизменяемые) данные по своей природе являются поточно-ориентированными - нет риска для одновременного чтения несколькими потоками одних и тех же данных только для чтения, потому что они никогда не изменятся!

Маркировка переменной как const в C ++ делает ее доступной только для чтения и, следовательно, безопасной для потоков.

14
12.12.2008 09:06:00
Предполагая, что вы не используете mutable нигде ;-)
Leon Timmermans 12.12.2008 09:30:42
Инициализация обычно есть. Зачем вам делиться объектом, который не был полностью инициализирован?
Greg Rogers 12.12.2008 15:20:38
также предполагая, что все функции-члены являются реентерабельными (то есть не имеют статических объектов или других общих данных)
Johannes Schaub - litb 12.12.2008 16:46:51
У меня был некоторый параллельный код с ошибкой, и я обнаружил, что я делаю, казалось бы, «безобидную» запись в переменную-член, что приводило к несущественной утечке памяти. constХорошим правилом является маркировка методов, которые будут выполняться несколькими потоками !
bobobobo 13.08.2011 17:23:15
-1, вводит в заблуждение ... игнорирует проблемы с обеспечением последовательных проблем согласованности.
NoSenseEtAl 28.12.2012 06:11:26

Функция-член const не должна изменять состояние, что делает безопасным вызов из нескольких потоков одновременно. Однако безопасность потока не является целью const, и C ++ предоставляет ключевое слово mutable и const_cast, означающее, что const фактически не гарантирует безопасность потока и на него нельзя полагаться для этой цели.

6
12.12.2008 09:22:23

Const-функции не являются поточно-ориентированными. Как правило, вы можете вызывать методы объекта const из разных потоков одновременно, но если вы вызываете не const и метод const из разных потоков, вы получаете условие гонки. Проверь это:

class Foo
{
    size_t size_;
public:
    ...
    size_t get_size() const
    {
        return size_
    }
};

class Bar
{
    boost::shared_ptr<Foo> foo_;
public:
    //accessor
    size_t get_size() const
    {
        size_t size = 0;
        if (foo_)
            size = foo_->size();
        return size;
    }
    //modifiers
    void init()
    {
        foo_ = new Foo;
    }

    void clear()
    {
        foo_ = boost::shared_ptr<Foo>();
    }
};

Если кто-то вызовет метод init, а затем вызовет методы clear и get_size одновременно, это приведет к нарушению доступа. Вы должны использовать идиому блокировки чтения-записи. Несколько аксессоров могут быть вызваны одновременно, и только один модификатор может быть вызван одновременно. Exemple:

class Bar
{
    boost::shared_ptr<Foo> foo_;
    mutable tbb::spin_rw_mutex lock_;
public:
    //accessor
    size_t get_size() const
    {
        size_t size = 0;
        //lock modifiers
        rw_mutex_type::scoped_lock lock(mutex, false);
        if (foo_)
            size = foo_->size();
        return size;
    }
    //modifiers
    void init()
    {
        //lock accessor and modifiers
        rw_mutex_type::scoped_lock lock(mutex, true);
        foo_ = new Foo;
    }

    void clear()
    {
        //lock accessor and modifiers
        rw_mutex_type::scoped_lock lock(mutex, true);
        foo_ = boost::shared_ptr<Foo>();
    }
};

tbb :: spin_rw_lock - это класс мьютекса из библиотеки потоковых блоков сборки

4
12.12.2008 10:09:05
Действительно: constness помогает только создавать приложения,
xtofl 12.12.2008 11:04:10

C ++ const позволяет использовать неконстантные псевдонимы, такие как:

Foo myVar;
const Foo* ptr1;
Foo* ptr2;

Учитывая это, const не дает никаких гарантий относительно неизменности ваших данных, даже если вы не выполняете кастинг или что-либо еще, чтобы обойти это. Если вы обращаетесь к myVar через ptr1, вы не можете изменить его через ptr1 (при условии, что я правильно понял синтаксис; это было намерением). Однако, он все еще может измениться через ptr2. То, что вы действительно хотите, это отдельная неизменная конструкция. Этого не существует в C ++.

4
15.01.2009 20:33:27

Const и Thread Safety - это ортогональные понятия.

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

3
22.02.2012 19:29:10