命名空间中的全局变量 - 值在线程中不同

时间:2012-06-26 23:44:51

标签: c++ multithreading c++11 atomic

考虑以下szenario:

  • 两个不同的网络端口,每个网络端口都在其自己的线程中boost::asio
  • 1个端口正在接收和处理数据 - class DataConnection包含在std::thread
  • 1个端口用于发送包含在class StatConnection
  • 中的统计信息std::thread

为计算连接数(以及其他小数据),我的想法是在static内使用namespace变量,如:

#include <atomic>

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

这适用于DataConnection类。在这里,我在c'tor中增加counter并查看值增量。

但我的counter课程中的StatConnection始终是0

为什么会发生这种情况?

我尝试了一些替代方案:

  • std::atomic<long>交换static volatile long:没有任何区别。
  • 使用不带static关键字的命名空间。

然后我收到了链接器错误:

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

那么为什么线程之间count的值不同?

1 个答案:

答案 0 :(得分:9)

命名空间范围中的

static引入了内部链接,因此每个翻译单元都有自己的counter副本 - 与您实际想要的完全相反!

使用extern代替标题:

//foo.h:
#include <atomic>

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

然后在一个翻译单元中定义变量:

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

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