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;
}

如果不使用 atomic ,我可以有初始化为 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 或许多其他库)使用互斥锁或类似锁保护它。

否则,您将遇到数据竞争,给出未定义的行为。

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

于 2012-08-29T15:00:48.540 回答