3

使用: VC++ 2013

concurrency::concurrent_vector<datanode*> dtnodelst

ときどきdtnodelst->at(i)....無効なアドレス(0XCDCD .. ofc)を取得していますが、これはプッシュバックした後に原因ではないはずです。アイテムを削除したり削除したりしません(削除しても削除された古いアドレスを返しました...しかし、私は削除していないので、そうではありません)

dtnodelst itm = new dtnodelst ();
....
dtnodelst->push_back(itm);

何が起こっているのかについてのアイデアはありますか?

ps Windows スレッド プールを使用しています。時々.. 800万回の挿入と検索を実行でき、すべてがうまくいきます..しかし、時には200回の挿入と検索でさえ失敗します。私はちょっと迷っています。どんな助けでも大歓迎です!!

よろしくお願いします

参考までに実際のコード

ps何か足りないのですか、それとも適切なフォーマットでコードを過去にするのは面倒ですか? 以前はオートアラインだったのを覚えています... -_-

struct datanode {       
     volatile int nodeval;
     T val;
};
concurrency::concurrent_vector<datanode*> lst
inline T find(UINT32 key)
{
    for (int i = 0; i < lst->size(); i++)
    {
       datanode* nd = lst->at(i);
       //nd is invalid sometimes
       if (nd)  
       if (nd->nodeval == key)
       {
         return (nd->val);
       }
    }
    return NULL;
}
inline T insert_nonunique(UINT32 key, T val){
   datanode* itm = new datanode();
   itm->val = val;
   itm->nodeval = key;
   lst->push_back(itm);
   _updated(lst);                       
   return val;
}
4

2 に答える 2

5

問題は、concurrent_vector::size()まだ構築されていない要素 (メモリにガベージが含まれている場所) への参照を取得できるため、完全にスレッドセーフではないのを使用することです。Microsoft PPL ライブラリ (concurrency::名前空間で提供) は Intel TBB 実装を使用しconcurrent_vector、TBBリファレンスは次のように述べています。

size_type size() const| | 戻り値: ベクター内の要素の数。結果には、いずれかの拡張メソッドへの同時呼び出しによって割り当てられているが、まだ構築中の要素が含まれる場合があります。

詳細な説明と考えられる解決策については、私のブログを参照してください。

TBB では、 size() がカウントする前に新しく割り当てられたメモリをゼロで埋めるために、tbb::zero_allocator基になるアロケータとしてを使用するのが最も合理的な解決策です。concurrent_vector

concurrent_vector<datanode*, tbb::zero_allocator<datanode*> > lst;

次に、条件if (nd)はまだ準備ができていない要素を除外します。

于 2014-08-18T16:42:52.500 に答える
-1

volatileの代わりにはなりませんatomic<T>volatile同期を提供する目的で使用しないでください。

呼び出しの全体的なアイデアfind、同時コンテキストでは意味がありません。関数が 1 つの値を反復処理するとすぐに、別のスレッドによって変更されて、探している値になる可能性があります。または、必要な値であるが、他の値に変更されている可能性があります。または、 が返されるとすぐにfalse、求めている値が追加されます。そのような関数の戻り値はまったく無意味です。size()これは、実装が機能しない理由の良い部分です。

並行データ構造の状態を検査することは、情報を取得した瞬間に無効になるため、非常に悪い考えです。正しく実行するために構造の状態を知る必要のない操作を設計するか、操作中にすべての変更をブロックする必要があります。

于 2014-08-18T17:06:57.847 に答える