繁体   English   中英

在运行循环之外声明,分配和取消分配线程局部指针变量

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM