0

分間隔に基づいて内部トラフィックを監視する必要があるため、次のようなことを行うことにしました。

Flow{
   void send();
   static uint accumulator;
}

//Only single thread call to send
void Flow::sendPacket(pck){
   accumulator+=pck.size();
   do();
}

//Only single thread call to monitor . **No the same thread that call to send!**
Monitor::monitor(){
   //Start monitor
   Flow::accumulator = 0;
   sleep(60);
   rate  = accumulator/60;
}

アトミックを使用せずに、0に初期化されないリスクが正しく発生しない可能性はありますか?

私の懸念は、アトミックでさえinitを保証しないことです。なぜなら、同時にinitを0に監視し、同時に累積が古い値で行われる場合、新しい累積値はinit値ではなく、古い値に基づくからです。 。

さらに、私は原子のペナルティから懸念しています。sendはパケットごとに呼び出されます。

4

2 に答える 2

5

Volatileはマルチスレッドには役立ちません。accumulator別のスレッドが値を読み取っているときに、の値が同時に更新されるのを防ぐ必要があります。C ++ 11を使用している場合は、accumulatorアトミックにすることができます。std::atomic<uint> accumulator;それ以外の場合は、その値へのすべてのアクセスの周りでミューテックスをロックする必要があります。

于 2012-08-29T14:59:19.890 に答える
1

volatileスレッド間でデータを共有するために必要でも十分でもないので、使用しないでください。

複数のスレッドからアクセスされる可能性がある場合は、次のいずれかを行う必要があります。

  • C ++ 11アトミックライブラリを使用してアクセスをアトミックにするか、使用できない場合はコンパイラ固有の言語拡張機能を使用します。
  • C ++ 11スレッドライブラリ、またはその他のライブラリ(Boost.Thread、POSIXスレッド、Intel TBB、Windows API、またはその他多数)を使用して、ミューテックスまたは同様のロックで保護します。

そうしないと、データの競合が発生し、未定義の動作が発生します。

1つのスレッドだけがアクセスできる場合は、特別なことをする必要はありません。

于 2012-08-29T15:00:48.540 に答える