2012-12-13 19 views
5

C++ 11アトミック操作でunique_ptrを安全に移動できますか?スレッドセーフunique_ptr move

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

をし、ミューテックスの必要性を回避:

現在、私は、私は単純に宣言するように、いくつかのよりエレガントな方法があるかどうかを疑問に思って、この

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

のようなコードを持っています。またはおそらく私はここでロックについて気にする必要はありませんし、std :: moveはすでに原子的ですか?

は研究の後、私は今のところ、それは私には思える行わ:

  • 自体を動かす:: stdがアトミックではなく、同時に私のメソッドを呼び出す周りにそうでない2つのスレッドが2つのコピーで終わるかもしれないいくつかの同期を持っている必要がありますいくつかの未定義のポインタの
  • std :: atomic宣言が私のためにコンパイルされますが、初期化して移動を行う方法がわかりません。

答えて

2

いいえ、これはできません。

に渡す値Tは簡単にコピー可能である必要があります。std::unique_ptrはコピーできません。 std::atomic::loadまたはstd::atomic::storeのような操作では、T個のオブジェクトを値で取得します。

std::atomicの中の何かをパッキングすることは、値atomicからの操作も行いません。

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

コードを見るときに私がうんざりしていたことの1つは、borrowSyncToken関数の目的です。借用と呼ばれていますが、std::unique_ptrを移動して、トークンの所有権を呼び出し元に渡します。所有権をどのように戻し、現在DataManagerがトークンを所有していないときに他のスレッドが取得するのですか?

+0

std :: shared_ptrの回答とディスカッションをありがとう。その目的のために、コードは簡略化されていますが、それでも、nullptrを後のスレッドに返して、呼び出し側がトークンが利用できないことを知ることができるようにします。ここで解決された問題は、私は他のコメントで説明します。 –

+0

クライアントは、読み込み、書き込みの2種類の操作をDataManagerで行います。 1人のクライアントだけがその時間に書き込むことができます。 **クライアントはスレッドではありません** - 場合によっては時々、クライアント用にバックグラウンドジョブが起動されることがあります。読み取り/書き込みは、単純な操作ではなく、DataManagerとクライアント間の複雑な通信プロトコルに従います。クライアント要求はトークンが利用可能になるまでブロックされる必要はありませんが、時には積極的に拒否されることもあります。混乱を避けるために、このSyncToken - WriterはSyncTokenを借りて、returnSyncToken(unique_ptr )を呼び出す必要がありました。 –