Атомарный обмен указателя с nullptr

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

 LARGE_INTEGER* ptr; // field

 void method()
 {
       LARGE_INTEGER* local = ptr;
       ptr = nullptr;
 }

Итак, я хочу сохранить указатель из поля в локальный указатель и сразу же установить для этого поля значение nullptr.

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


person M.kazem Akhgary    schedule 06.08.2017    source источник
comment
LARGE_INTEGER* local = InterlockedExchangePointer(&ptr, nullptr); Может потребоваться приведение к первому аргументу.   -  person Igor Tandetnik    schedule 06.08.2017
comment
@IgorTandetnik, это может быть без блокировки?   -  person M.kazem Akhgary    schedule 06.08.2017
comment
Как показано, он не имеет блокировки.   -  person Igor Tandetnik    schedule 06.08.2017
comment
@IgorTandetnik говорит, что LARGE_INTEGER** несовместим с параметром типа volatile PVOID *   -  person M.kazem Akhgary    schedule 06.08.2017
comment
этот каст в порядке? (он компилируется, но не уверен в поведении во время выполнения) LARGE_INTEGER* local = (LARGE_INTEGER*)InterlockedExchangePointer((PVOID*)&_ptr, nullptr); если это так, вы можете опубликовать это как ответ, я очень ценю это, спасибо @IgorTandetnik   -  person M.kazem Akhgary    schedule 06.08.2017
comment
Используйте std::atomic или повторите эквивалент.   -  person GManNickG    schedule 06.08.2017


Ответы (1)


Начиная с С++ 11 вы можете использовать std::atomic для этой цели следующим образом:

#include <atomic>
LARGE_INTEGER value;
std::atomic<LARGE_INTEGER*> ptr{&value};
LARGE_INTEGER* local = ptr.exchange(nullptr);
person Dev Null    schedule 06.08.2017