Как реализовать ориентированный на многопотоковое исполнение подсчет ссылок в C++

Похоже, мы можем придумать это решение, мой друг:

first_array.each_with_index { |vgpop, i| vgpop.name = second_array[i] }
19
задан Fabian 18 September 2008 в 14:33
поделиться

7 ответов

В наше время можно использовать Boost/TR1 shared_ptr<> интеллектуальный указатель для хранения ссылки считаемыми ссылками.

Работает отлично; никакая суета, никакой беспорядок. shared_ptr<> класс заботится обо всей блокировке, необходимой на refcount.

11
ответ дан 30 November 2019 в 04:44
поделиться

Тот конкретный код отправил, в котором ddj статья добавляет дополнительную сложность для составления ошибок в использовании интеллектуальных указателей.

А именно, если Вы не можете гарантировать, что интеллектуальный указатель не изменится в присвоении на другой интеллектуальный указатель, Вы делаете его неправильно или делаете что-то очень ненадежное для начала. Если интеллектуальный указатель может измениться, будучи присвоенным другому интеллектуальному указателю, который означает, что делающий уроки код не владеет интеллектуальным указателем, который является подозреваемым для начала.

0
ответ дан 30 November 2019 в 04:44
поделиться

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

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

вопрос эффективных: pthread библиотека так эффективна, как это может быть и все еще гарантировать, что взаимоисключающая блокировка является атомарной для Вашей ОС.

это дорогой: Вероятно. Но для всего, что требует гарантии, существует стоимость.

0
ответ дан 30 November 2019 в 04:44
поделиться

В VC ++, можно использовать _InterlockedCompareExchange.

do
   read the count
   perform mathematical operation
   interlockedcompareexchange( destination, updated count, old count)
until the interlockedcompareexchange returns the success code.

На других платформах/компиляторах, используйте соответствующее внутреннее для БЛОКИРОВКИ инструкция CMPXCHG, что _InterlockedCompareExchange MS выставляет.

4
ответ дан 30 November 2019 в 04:44
поделиться

Строго говоря необходимо будет ожидать до C++ 0x, чтобы смочь написать ориентированный на многопотоковое исполнение код в чистом C++.

На данный момент, можно использовать Posix или создать собственные независимые от платформы обертки вокруг, сравнивают и подкачивают и/или взаимно блокировал инкремент/декремент.

3
ответ дан 30 November 2019 в 04:44
поделиться

Win32 InterlockedIncrementAcquire и InterlockedDecrementRelease (если Вы хотите быть в безопасности и заботиться о платформах с возможным переупорядочением, следовательно необходимо выпустить барьеры памяти одновременно) или InterlockedIncrement и InterlockedDecrement (если Вы уверены, что останетесь x86), являются атомарными и сделают задание.

Тем не менее Boost/TR1 shared_ptr<> обработает все это для Вас, поэтому если Вы не должны будете реализовывать его самостоятельно, Вы, вероятно, приложите все усилия для придерживаний его.

2
ответ дан 30 November 2019 в 04:44
поделиться

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

, Учитывая это, может быть эмпирическое правило, применимое здесь (я рад быть исправленным!)

, Если следовать вещи относятся к Вам:

  • у Вас есть сложные структуры данных, которые были бы трудными записать деструкторы для (или где семантика значения стиля STL будет несоответствующей дизайном), таким образом, Вам будут нужны интеллектуальные указатели, чтобы сделать это для Вас, и
  • Вы используете несколько потоков, которые совместно используют эти объекты, и
  • Вы заботитесь о производительности, а также правильности

... затем фактическая сборка "мусора" может быть лучшим выбором. Хотя GC имеет плохую репутацию производительности, это - весь родственник. Я полагаю, что это соответствует очень благоприятно блокировке интеллектуальных указателей. Это была важная часть того, почему команда CLR выбрала истинный GC вместо чего-то с помощью подсчета ссылок. См. эта статья , в особенности это абсолютное сравнение того, что означает ссылочное присвоение, есть ли у Вас продолжение подсчета:

не касательно подсчета:

a = b;

касательно подсчета:

if (a != null)
    if (InterlockedDecrement(ref a.m_ref) == 0)
            a.FinalRelease();

if (b != null)
    InterlockedIncrement(ref b.m_ref);

a = b;
1
ответ дан 30 November 2019 в 04:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: