it-swarm.cn

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

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。是否有一些合理的方法(标准因为我希望它是便携式的)来做到这一点?

70
NoSenseEtAl

可移植的解决方案是将您自己生成的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上说:an identifier )。即使它由operator<<生成的文本表示是 未指定 ,因此您不能依赖它作为数字的表示。

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

27
R. Martinho Fernandes

你只需要这样做

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

获得size_t

来自 cppreference

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

69
888

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

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

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

22
Mike

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

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

gettid(),几乎肯定不是可移植的,但它确实返回了GDB友好值。

6
tgoodhart

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

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相比,重写很容易。 :)

4
NoSenseEtAl

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

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

3
Alexey Polonsky

这取决于你想要使用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。

2
Pandrei

这样,应该工作:

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

请记住包含库sstream

2
Federico Rizzo

也许这个解决方案对某人有帮助。第一次调用它main()。警告:names无限增长。

std::string currentThreadName(){
    static std::unordered_map<std::thread::id,std::string> names;
    static std::mutex mtx;

    std::unique_lock<std::mutex> lock(mtx);

    auto id = std::this_thread::get_id();

    if(names.empty()){
        names[id] = "Thread-main";
    } else if(names.find(id) == names.end()){
        std::stringstream stream;
        stream << "Thread-" << names.size();
        names[id] = stream.str();
    }

    return names[id];
}
1
geh