我想在多线程进程中实现一个高性能计数器,像这样,每个线程都有一个名为“t_counter”的线程本地计数器来计数查询(incr 1/query),并且在“计时器线程”中有一个名为“global_counter”的计数器”,我想要的是每一秒,global_counter都会获取每个t_counter并将它们添加到global_counter,但我不知道如何获取“计时器线程”中的每个t_counter值。另外,线程局部值将位于主内存中的哪一部分? .data 或堆或其他?如何动态分配内存大小(可能有10个线程或100个线程)? x86-64是否使用段寄存器存储这样的值?
从第二个问题开始,您可以在这里找到所有规格。
总结一下,线程局部变量定义在.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; });
}
https://github.com/apache/brpc/tree/master/src/bvar 这就是你需要的............