在我去过的几个工作场所看到的一个设计问题,但没有一个令人满意的解决方案:
假设您有一个具有动态线程数的系统。
每个线程都必须访问一组“单例”,单例每个线程只有一个实例(因此它们不是真正的单例,而是每个线程的单例)
这组单例在编译时是已知的。
每个单例都有一个默认构造函数(为了简化事情,不过,没有这个约束的解决方案会很好)
一个满意的解决方案应该有以下几点:
每个线程都可以在 o(1) 时间内访问它的任何单例
对单例的访问是无锁的
将单例添加到“单例集”不需要在集端编写新代码
“单例集”在编译期间填充
我不确定这样的设计是否可行。如果是,我认为它需要一点元编程。
提前感谢您的任何见解。
最佳答案
线程局部变量很好地解决了这个问题。
// in .h
class ThreadSingleton
{
private:
static __thread ThreadSingleton* thread_specific_instance;
public:
static ThreadSingleton* get() { return thread_specific_instance; }
ThreadSingleton();
~ThreadSingleton();
};
// in .cc
__thread ThreadSingleton* ThreadSingleton::thread_specific_instance;
ThreadSingleton::ThreadSingleton() {
if(thread_specific_instance)
std::abort(); // one instance per thread please
thread_specific_instance = this;
}
ThreadSingleton::~ThreadSingleton() {
thread_specific_instance = 0;
}
// usage
int main() {
// on thread entry
ThreadSingleton x;
// later anywhere in the thread
ThreadSingleton* px = ThreadSingleton::get();
}
每个线程都会在堆栈的某处创建ThreadSingleton
,通常是在线程函数中。稍后可以通过 ThreadSingleton::get()
从该线程中的任何位置访问 ThreadSingleton
,它返回调用线程的单例。 (上面可以做一个模板来包装任何其他类,为了说明简单我没有这样做)。
性能方面访问线程局部变量不需要任何调用(不同于使用 pthread_key_create
创建的线程特定存储)参见 http://www.akkadia.org/drepper/tls.pdf了解更多详情。
关于c++ - 在 C++ 中包含和访问线程全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11556298/