首页 文章

如何在c 11中获取整数线程id

提问于
浏览
68

c 11有可能获得当前的线程ID,但它不能转换为整数类型:

cout<<std::this_thread::get_id()<<endl;

输出:139918771783456

cout<<(uint64_t)std::this_thread::get_id()<<endl;

错误:从类型'std :: thread :: id'到类型'uint64_t'的无效强制转换与其他类型相同:从类型'std :: thread :: id'到类型'uint32_t'的无效强制转换

我真的不想做指针转换来获取整数线程ID . 是否有一些合理的方法(标准因为我希望它是便携式的)来做到这一点?

8 回答

  • 2

    可移植的解决方案是将您自己生成的ID传递给线程 .

    int id = 0;
    for(auto& work_item : all_work) {
        std::async(std::launch::async, [id,&work_item]{ work_item(id); });
        ++id;
    }
    

    std::thread::id 类型仅用于比较,而不是用于算术(即,如在can上所述:标识符) . 即使是由 operator<< 生成的文本表示也未指定,因此您不能依赖它作为数字的表示 .

    您还可以使用 std::thread::id 值的映射到您自己的id,并在线程之间共享此映射(具有适当的同步),而不是直接传递id .

  • 3

    你只需要这样做

    std::hash<std::thread::id>{}(std::this_thread::get_id())
    

    得到 size_t .

    来自cppreference

    std :: thread :: id类的std :: hash模板特化允许用户获取线程标识符的哈希值 .

  • 27

    另一个id(想法?^^)将使用stringstreams:

    std::stringstream ss;
    ss << std::this_thread::get_id();
    uint64_t id = std::stoull(ss.str());
    

    如果您在出现问题时不想要例外,请使用try catch ...

  • 2

    一个想法是使用线程本地存储来存储变量 - 无论什么类型,只要它符合线程本地存储的规则 - 然后使用该变量的地址作为“线程ID” . 显然任何arithemetic都没有意义,但它将是一个完整的类型 .

    后代: pthread_self() 返回 pid_t 并且是posix . 对于便携式的某些定义,这是便携式的 .

    gettid() ,几乎肯定不是便携式的,但它确实返回了GDB友好值 .

  • 4

    我真的不知道这有多快,但这是我设法猜测的解决方案:

    const size_t N_MUTEXES=128;//UINT_MAX,not 128  for answer to my original question
    hash<std::thread::id> h;
    cout<<h(std::this_thread::get_id())%N_MUTEXES<<endl;
    

    再一次,我开始认为获取指向结构的指针并将其转换为unsigned int或uint64_t就是答案...编辑:

    uint64_t get_thread_id()
    {
        static_assert(sizeof(std::thread::id)==sizeof(uint64_t),"this function only works if size of thead::id is equal to the size of uint_64");
        auto id=std::this_thread::get_id();
        uint64_t* ptr=(uint64_t*) &id;
        return (*ptr);
    }
    int main()
    {
        cout<<std::this_thread::get_id()<<"  "<<get_thread_id()<<endl;
    }
    

    static_assert以防止地狱般的问题:)与追捕这种bug相比,重写很容易 . :)

  • 67

    thread::native_handle() 返回 thread::native_handle_type ,这是 long unsigned int 的typedef .

    如果线程是默认构造的,则native_handle()返回0.如果附加了OS线程,则返回值为非零(在POSIX上为pthread_t) .

  • 6

    这取决于你想要使用thread_id的内容;您可以使用:

    std::stringstream ss;
    ss << std::this_thread::get_id();
    uint64_t id = std::stoull(ss.str());
    

    这将生成一个独特的id,伴随着你的过程;但是有一个限制:如果启动同一进程的多个实例,并且每个实例都将其线程ID写入公共文件,则无法保证thread_id的唯一性;事实上,你很可能会有重叠 . 在这种情况下,您可以执行以下操作:

    #include <sys/time.h>
    timespec ts;
    clock_gettime(CLOCK_REALTIME, &ts);
    uint64_t id = (ts.tv_sec % 1000000000) * 1000000000 + ts.tv_nsec;
    

    现在,您可以保证全系统的独特线程ID .

  • 22

    这样,应该工作:

    std::stringstream ss;
    ss << std::this_thread::get_id();
    int id = std::stoi(ss.str());
    

    请记住包含库sstream

相关问题