c ++线程安全累加器

时间:2012-08-29 14:56:01

标签: c++ multithreading

我需要根据分钟间隔监控内部流量,所以我决定做这样的事情:

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并且同时使用旧值进行累积,则新累积值将基于旧值而不是初始值。

另外我关注原子惩罚。每个数据包都会调用send。

2 个答案:

答案 0 :(得分:5)

Volatile对多线程没有帮助。您需要防止同时更新accumulator的值并在另一个线程正在读取值的同时更新。如果您有C ++ 11,则可以使accumulator原子:std::atomic<uint> accumulator;否则,您需要锁定所有对其值的访问的互斥锁。

答案 1 :(得分:1)

volatile对于在线程之间共享数据既不必要也不够,所以不要使用它。

如果它可能被多个线程访问,那么您必须:

  • 使用C ++ 11原子库或特定于编译器的语言扩展(例如,如果不可用)使访问成为原子,或者
  • 使用Cute 11或类似的锁,使用C ++ 11线程库或其他库(Boost.Thread,POSIX线程,Intel TBB,Windows API或许多其他库)来保护它,如果这不可用的话。

否则,您将有一个数据竞赛,给出未定义的行为。

如果只有一个线程可以访问它,那么你不需要做任何特别的事情。

相关问题