[英]Declare, allocate and deallocate thread-local pointer variables outside the run loop
我有一个线程化的管道和过滤器实现,我想在其中一个过滤器中使用线程本地副本。 我自己没有实现运行循环。 相反,基本Filter类在获取要处理的数据时会在每个过滤器上调用process()方法。
在这种情况下,使用thread_locals存在两个问题:1)我无法在process()方法中声明thread_locals,因为要点是在调用process()方法时重用线程本地。
下面的示例代码:
void process(SomeInput in) {
thread_local SomeClass* someClass = nullptr;
if (someClass == nullptr) someClass = new SomeClass(params);
// do stuff here...
}
因此,在上面我初始化了SomeClass的thread_local实例。 但是我不会取消分配它,因为只要有新数据到达,process()就会被同一线程的运行循环调用。 显然,该类永远不会被释放。 坏。
2)我在过滤器实现中添加了threadCleanup()方法,该方法在过滤器停止运行(并且其线程停止)时立即被调用。 虽然那将需要声明thread_local成员变量,例如:
class SomeFilter : public Filter <...> {
// ...
private:
thread_local SomeClass* _someClass;
}
但这不适用于类并引发:“ thread_local仅在变量声明中被允许”
在这种情况下,声明,分配和取消分配线程局部的正确方法是什么?
修复原始问题,而不是为自己创建的新问题:
只需使原始代码使用std::unique_ptr
。 您甚至可以将其单行执行, 因为thread_local
暗含static
,因此它只需初始化一次,而无需对nullptr
进行每次调用测试:
void process(SomeInput in) {
thread_local std::unique_ptr<SomeClass> someClass(new SomeClass(params));
// do stuff here...
}
给定线程第一次调用process
,将为该线程初始化unique_ptr
; 当该线程退出时,销毁unique_ptr
并收集该线程的SomeClass
实例, 因为在线程exit上调用thread_local
析构函数 。
请注意,如果someClass
很小,则可以将其直接存储在thread_local
存储中,而不必在thread_local
存储指向堆的unique_ptr
,这将使您完全避免unique_ptr
,因为如前所述, thread_local
表示static
并在线程退出时调用析构函数:
void process(SomeInput in) {
thread_local SomeClass someClass(params);
// do stuff here,
// using someClass. instead of someClass-> for member/method access,
// and &someClass where you used to use someClass if something needs a raw
// pointer (the raw pointer is definitely sticking around until thread
// exit after all)
}
使用unique_ptr
方法可能仍然是有利的(线程本地存储可能受到限制/速度很慢,因此将其余的类存储在普通堆内存中可能是值得的)。
您要查找的语法是成员变量上的static thread_local
:
class SomeFilter : public Filter <...> {
// ...
private:
static thread_local SomeClass* _someClass;
}
与其执行手动清理,不如将_someClass
封装在unique_ptr
,因为线程本地在线程退出时被销毁了:
static thread_local std::unique_ptr<SomeClass> _someClass;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.