如何获得整数线程ID在C + + 11
c ++ 11有可能获得当前的线程ID,但它不能转换为整数types:
cout<<std::this_thread::get_id()<<endl;
输出:139918771783456
cout<<(uint64_t)std::this_thread::get_id()<<endl;
错误:从types'std :: thread :: id'转换为types'uint64_t'无效从其他types相同:从types'std :: thread :: id'无效转换types'uint32_t'
我真的不想做指针投射得到整数线程ID。 有没有一些合理的方法(标准,因为我希望它是便携式)做到这一点?
便携式解决scheme是将您自己生成的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
types仅用于比较,而不用于算术(即如can表示的那样:一个标识符 )。 即使由operator<<
产生的文本表示也没有被指定 ,所以你不能依赖它作为数字的表示。
你也可以使用std::thread::id
值映射到你自己的id,并在线程间共享这个映射(通过适当的同步),而不是直接传递id。
你只需要做
std::hash<std::thread::id>{}(std::this_thread::get_id())
得到一个size_t
。
从cppreference :
用于
std::thread::id
类的std::hash
的模板特化允许用户获得线程标识符的散列。
另一个id(想法?^^)将是使用stringstreams:
std::stringstream ss; ss << std::this_thread::get_id(); uint64_t id = std::stoull(ss.str());
如果你不想在例外情况下出现exception,请使用try catch。
一个想法是使用线程本地存储来存储一个variables – 只要符合线程本地存储的规则,什么types都不重要,然后使用该variables的地址作为“线程ID”。 很明显,任何一个arithemetic都不会有意义,但它将是一个完整的types。
后人: pthread_self()
返回一个pid_t
并且是posix。 这是便携式的一些定义便携式。
gettid()
几乎肯定不是可移植的,但它确实返回了一个GDB友好的值。
我真的不知道这是多快,但这是我成功的解决scheme:
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,以防止地狱般的问题:)重写是比较容易find这种types的错误。 🙂
这取决于你想使用什么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系统。
这样,应该工作:
std::stringstream ss; ss << std::this_thread::get_id(); int id = std::stoi(ss.str());
记得包括图书馆的stream