我想在多线程进程中实现一个高性能计数器,像这样,每个线程都有一个名为“t_counter”的线程本地计数器来计算查询(incr 1/query)并且在“timer thread”中有一个名为“global_counter”,我想要的是每一秒,global_counter会获取每个t_counter(s)并将它们添加到global_counter,但我不知道如何在“timer thread”中获取每个t_counter值。另外,哪个部分将线程本地值放在主内存中? .data 或堆或其他?如何动态分配内存大小(可能有 10 个线程或 100 个线程)? x86-64 是否使用段寄存器存储这样的值?
最佳答案
从您的第二个问题开始,您可以找到所有规范 here .
总结一下,线程局部变量定义在.tdata/.tbss中。这些有点类似于 .data,但是访问它们是不同的。这些部分按线程复制。实际变量偏移量在运行时计算。
变量由 .tdata 中的偏移量标识。说到 x86_64 它将使用 FS 段寄存器找到 TCB(线程控制 block ),使用存储在那里的数据结构它将定位变量所在的线程本地存储。请注意,如果可能,所有分配都是延迟完成的。
现在,关于你的第一个问题——我不知道有什么方法可以只列出来自另一个线程的所有线程局部变量,我怀疑它是否可用。
但是,线程可以获取指向线程变量的指针,并将其传递给另一个线程。所以您可能需要一些注册机制。
每个新线程都会将自己注册到某个主存储,然后在终止时取消注册。注册和注销由您负责。
从原理上讲,它看起来像这样:
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; });
}
关于C++线程本地计数器实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70601992/