Как сделать, сравнивают и увеличивают атомарно?

В моей попытке к develope ориентированный на многопотоковое исполнение C++ слабый шаблонный класс указателя я должен проверить флаг, что указание на объект все еще живо, если да затем увеличивают подсчет ссылок объекта, и я должен сделать оба шага атомарно.

Я знаю существование функций intrinsics, обеспеченных компилятором, например, _InterlockedCompareExchange () и _InterlockedIncrement (). Но то, что я хочу, является interlockedCompareIncrement () функция, есть ли эффективный способ моделировать это внутреннее использование других примитивов, по крайней мере, на платформе Windows x86?

10
задан Ricky Lung 9 November 2010 в 14:13
поделиться

3 ответа

Предположим, что значение - это ваша переменная флага. Он должен быть объявлен изменчивым .

long curvalue;
long newvalue;

do
{
    curvalue = value;
    newvalue = curvalue + 1;
}
while( _InterlockedCompareExchange( &value, newvalue, curvalue ) != curvalue );

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

Если вы хотите сравнить два значения одновременно, лучше всего упаковать оба значения в одну переменную, а затем работать с этой единственной переменной. Поскольку вы используете флаг в сочетании со счетчиком ссылок, я бы рекомендовал использовать самый младший бит значения в качестве «живого» флага, а затем увеличивать / уменьшать на 2 за раз. Это позволяет кодировать как флаг, так и счетчик ссылок в одну 32-битную переменную.

7
ответ дан 4 December 2019 в 02:25
поделиться

Если вы хотите, чтобы ваша библиотека работала на нескольких CPU или многоядерных машинах, вы должны использовать аппаратную поддержку, предоставляемую CPU. Вот несколько ссылок:

http://en.wikipedia.org/wiki/Test-and-set http://software.intel.com/en-us/forums/showthread.php?t=47498

Или вы должны использовать механизм блокировки, предоставляемый ОС. Such as

http://msdn.microsoft.com/en-us/library/ms684841%28VS.85%29.aspx или http://en.wikipedia.org/wiki/POSIX_Threads

1
ответ дан 4 December 2019 в 02:25
поделиться

Поскольку вы работаете на C ++, вы можете написать свой собственный ассемблерный код.

Возможно, это связано с Реализовать атомарное приращение с помощью атомарного свопа?

0
ответ дан 4 December 2019 в 02:25
поделиться
Другие вопросы по тегам:

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