c++线程本地计数器实现

问题描述 投票:0回答:2

我想在多线程进程中实现一个高性能计数器,像这样,每个线程都有一个名为“t_counter”的线程本地计数器来计数查询(incr 1/query),并且在“计时器线程”中有一个名为“global_counter”的计数器”,我想要的是每一秒,global_counter都会获取每个t_counter并将它们添加到global_counter,但我不知道如何获取“计时器线程”中的每个t_counter值。另外,线程局部值将位于主内存中的哪一部分? .data 或堆或其他?如何动态分配内存大小(可能有10个线程或100个线程)? x86-64是否使用段寄存器存储这样的值?

c++ thread-local
2个回答
2
投票

从第二个问题开始,您可以在这里找到所有规格。

总结一下,线程局部变量定义在.tdata / .tbss中。这些与 .data 有点相似,但访问它们是不同的。这些部分是按线程复制的。实际的变量偏移量是在运行时计算的。

变量由 .tdata 中的偏移量标识。对于x86_64,它将使用FS段寄存器来查找TCB(线程控制块),使用存储在那里的数据结构,它将定位变量所在的线程本地存储。请注意,如果可能的话,所有分配都会延迟完成。

现在,关于你的第一个问题 - 我不知道有一种方法可以只列出另一个线程中的所有线程局部变量,并且我怀疑它是否可用。

但是,线程可以获取指向线程变量的指针,并将其传递给另一个线程。所以你可能需要一些注册机制。

每个新线程都会将自己注册到某个主存储,然后在终止时取消注册。注册和注销由您负责。

从原理上讲,它看起来像这样:

thread_local int counter = 0;
std::map<std::thread::id, int *> regs;

void register() {
    // Take some lock here or other synchronization, maybe RW lock
    regs[std::this_thread::get_id()] = &counter;
}
void unregister() {
    // Again, some lock or other synchronization
    regs.erase(std::this_thread::get_id());
}

void thread_main() {
    register();
    counter++;
    unregister();
}

void get_sum() {
    // Again, some lock, maybe only read lock
    return std::accumulate(regs.begin(), regs.end(), 0,
        [](int previous, const auto& element)
        { return previous + *element.second; });
}

-1
投票

https://github.com/apache/brpc/tree/master/src/bvar 这就是你需要的............

© www.soinside.com 2019 - 2024. All rights reserved.