【问题标题】:C++ constexpr thread_local idC++ constexpr thread_local id
【发布时间】:2018-03-11 09:17:03
【问题描述】:

有什么方法可以在每个线程的 constexpr thread_local 变量中获取不同的值?

constexpr thread_local someType someVar = ......;

似乎支持 constexpr thread_local,但在这种情况下 thread_local 指示器似乎没有做任何事情。

【问题讨论】:

  • 您似乎有一些相互矛盾的要求。 constexpr 用于编译时常量,而线程是纯运行时概念。你想做什么?您要解决的实际问题是什么?请花一些时间阅读the XY problem 并思考它与这个问题的关系。
  • 你想用这个达到什么目的?
  • 我想检查编译时是否会从正确的线程调用某些东西
  • 您可能正在寻找std::this_thread::get_id()
  • 你不能那样做。调用发生在运行时,您不能在编译时进行运行时检查,这根本不可能。也许是时候考虑(或者更确切地说重新考虑)您的要求或设计?

标签: c++ c++14 constexpr thread-local


【解决方案1】:

如果您考虑一下您的问题,您自己就会明白为什么这是不可能的。

什么是constexpr

根据非正式标准网站cppreference

constexpr 说明符声明可以在编译时计算函数或变量的值。

编译器必须在编译时解析该值,并且该值在程序执行期间不应更改。

线程本地存储

相反,线程是一个运行时概念。 C++11 将线程概念引入到语言中,因此您可以说编译器可以“感知”线程概念。 但是,编译器不能总是预测一个线程是否会被执行(也许你只在特定的配置下运行这个线程),或者会产生多少个实例等等。

可能的实施

与其尝试使用 hacks 和技巧来强制对单个线程的特定模块/方法的访问,为什么不使用该语言的一个非常原始的特性?

您也可以使用简单的封装来实现这一点。只需确保“看到”您要保护的此方法的唯一对象是线程对象本身,例如:

#include <iostream>
#include <thread>
#include <chrono>

using namespace std;

class SpecialWorker
{
public:
    void start()
    {
        m_thread = std::move(std::thread(&SpecialWorker::run, this));
    }

    void join()
    {
        m_thread.join();
    }

protected:
    virtual void run() { protectedTask(); }

private:
    void protectedTask()
    {
        cout << "PROTECT ME!" << endl;
    }

    std::thread m_thread;
};

int main(int argc, char ** argv)
{
    SpecialWorker a;
    a.start();
    a.join();

    return 0;
}

请注意,此示例缺少错误处理,不是生产级代码!如果您打算使用它,请务必对其进行改进。

【讨论】:

    猜你喜欢
    • 2019-11-20
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    • 2018-12-06
    • 2019-01-27
    • 2018-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多