Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Global variable in namespace - Values differ in threads

Consider the following szenario:

  • 2 different network-ports via boost::asio each in its own thread
  • 1 port is receiving and processing data - class DataConnection wrapped in a std::thread
  • 1 port is for sending statistics class StatConnection also wrapped in a std::thread

For counting connections (and other small data pieces) my idea was to use a static variable inside a namespace like:

#include <atomic>

namespace app {
 namespace status {
   static std::atomic<long> counter = 0; 
 }
}

This works fine for the DataConnection class. Here I increment counter in the c'tor and see the value increments.

But counter in my StatConnection class is always 0

Why can this happen?

I've tried some alternatives:

  • exchanging std::atomic<long> for static volatile long: Did not made a difference.
  • using the namespace without static keyword.

Then I got linker errors:

multiple definition of `app::status::searchtime'
./src/status/Status.o:/[...]/include/status/Status.hpp:16: first defined here
[...]

So why is the value of count different between threads?

like image 754
kei1aeh5quahQu4U Avatar asked Jun 26 '12 23:06

kei1aeh5quahQu4U


1 Answers

static in namespace scope introduces internal linkage, so each translation unit will have its own copy of counter – quite the opposite of what you actually want!

Use extern instead, in the header:

//foo.h:
#include <atomic>

namespace app {
    namespace status {
        extern std::atomic<long> counter;
    }
}

Then define the variable in one translation unit:

//foo.cpp:
#include "foo.h"

namespace app {
    namespace status {
        std::atomic<long> counter{0L};
    }
}
like image 128
ildjarn Avatar answered Sep 24 '22 06:09

ildjarn