我需要根据分钟间隔监控内部流量,所以我决定做这样的事情:
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。
答案 0 :(得分:5)
Volatile对多线程没有帮助。您需要防止同时更新accumulator
的值并在另一个线程正在读取值的同时更新。如果您有C ++ 11,则可以使accumulator
原子:std::atomic<uint> accumulator;
否则,您需要锁定所有对其值的访问的互斥锁。
答案 1 :(得分:1)
volatile
对于在线程之间共享数据既不必要也不够,所以不要使用它。
如果它可能被多个线程访问,那么您必须:
否则,您将有一个数据竞赛,给出未定义的行为。
如果只有一个线程可以访问它,那么你不需要做任何特别的事情。