5

C++11 アトミック操作で unique_ptr を安全に移動することは可能ですか?

Currently I have a code like this

std::unique_ptr<SyncToken> DataManager::borrowSyncToken()
{
    std::unique_lock<std::mutex> syncTokenLock(syncTokenMutex);
    return std::move(syncToken);
}

I am wondering whether there is some more elegant way, like simply declaring:

std::atomic<std::unique_ptr<SyncToken>> syncToken;

and avoiding the need of mutex. Or possibly I don't need to care about the lock here at all and std::move is already atomic?

After research I made so far it seems to me:

  • the std::move itself is not atomic and needs to have some synchronization around otherwise 2 threads calling my method concurrently may end up with 2 copies of some undefined pointers.
  • the std::atomic declaration compiles for me, but I don't know how to initialize it and and make the move.
4

1 に答える 1

3

いいえ、これは不可能です。

T渡す値はstd::atomic簡単にコピーできる必要がありますが、そうでstd::unique_ptrはありません。値による T オブジェクトの likestd::atomic::loadまたはtake の操作。std::atomic::store

何かを a にパックしてstd::atomicも、値からの操作はアトミックになりません。

アトミック コンテキストで使用std::unique_ptrする場合は、リソースの管理に関して問題が発生する可能性があるという事実を考慮する必要があります。データを参照しているスレッドがまだいくつあるかはわかりません。この問題は、std::shared_ptrアトミック参照カウントを使用する で解決できます。(関数を使用して、本当にアトミックかどうかを確認する必要がありstd::atomic_is_lock_freeます。)

あなたのコードを調べたときに私がつまずいたことの 1 つは、borrowSyncToken関数の意図です。これは借用と呼ばれますが、トークンの所有権を呼び出し元にstd::unique_ptr渡すには、DataManager が現在トークンを所有していない場合、所有権がどのように返され、他のスレッドは何を取得しますか?

于 2012-12-13T20:57:42.137 に答える