Как получить идентификатор целочисленного потока в c++11
c++11 имеет возможность получения текущего идентификатора потока, но он не может быть приведен к целочисленному типу:
cout<<std::this_thread::get_id()<<endl;
выход : 139918771783456
cout<<(uint64_t)std::this_thread::get_id()<<endl;
ошибка: недопустимое приведение от типа 'std:: thread:: id 'к типу' uint64_t’
же для других типов:
недопустимого приведения типа ‘СТД::резьба::идентификатор’ для типа ‘uint32_t’
Я действительно не хочу делать приведение указателя, чтобы получить идентификатор целочисленного потока. Есть ли какой-то разумный способ (стандартный, потому что я хочу, чтобы он был портативным), чтобы сделать это?
8 ответов:
портативное решение состоит в том, чтобы передать свои собственные сгенерированные идентификаторы в поток.
int id = 0; for(auto& work_item : all_work) { std::async(std::launch::async, [id,&work_item]{ work_item(id); }); ++id; }The
std::thread::idтип должен использоваться только для сравнения, а не для арифметики (т. е. как говорится на can: an идентификатор). Даже его текстовое представление производитсяoperator<<и нет данных, поэтому вы не можете полагаться на это представление числа.вы также можете использовать карту
std::thread::idзначения для вашего собственного идентификатора, и поделиться этой картой (с правильным синхронизация) между потоками, вместо того, чтобы передавать идентификатор напрямую.
вам просто нужно сделать
std::hash<std::thread::id>{}(std::this_thread::get_id())и
size_t.С cppreference:
шаблон специализации
std::hashнаstd::thread::idкласс позволяет пользователям получать хэши идентификаторов потоков.
другое удостоверение личности (идея? ^^) было бы использовать stringstreams:
std::stringstream ss; ss << std::this_thread::get_id(); uint64_t id = std::stoull(ss.str());и используйте try catch, если вы не хотите исключения в случае, если что-то пойдет не так...
одной из идей было бы использовать локальное хранилище потоков для хранения переменной - не имеет значения, какой тип, если он соответствует правилам локального хранилища потоков - затем использовать адрес этой переменной в качестве вашего "идентификатора потока". Очевидно, что любая арифметика не будет иметь смысла, но это будет интегральный тип.
для потомков:
pthread_self()возвращает apid_tи является posix. Это портативный для некоторого определения портативного.
gettid(), почти наверняка не портативный, но он возвращает дружественное значение GDB.
Я действительно не знаю, как быстро это, но это решение мне удалось guestimate :
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 для предотвращения адских проблем:) переписать легко по сравнению с охотой на такого рода ошибку. :)
thread::native_handle()возвращаетthread::native_handle_type, который является typedef, чтобыlong unsigned int.если поток построен по умолчанию, native_handle () возвращает 0. Если к нему присоединен поток ОС, возвращаемое значение не равно нулю (это pthread_t на POSIX).
это зависит от того, что вы хотите использовать thread_id для; вы можете использовать:
std::stringstream ss; ss << std::this_thread::get_id(); uint64_t id = std::stoull(ss.str());это создаст уникальный идентификатор в процессе; но есть ограничение: если вы запускаете несколько экземпляров одного и того же процесса, и каждый из них записывает свои идентификаторы потоков в общий файл, уникальность thread_id не гарантируется; на самом деле очень вероятно, что у вас будут перекрытия. В этом случае вы можете сделать что-то вроде:
#include <sys/time.h> timespec ts; clock_gettime(CLOCK_REALTIME, &ts); uint64_t id = (ts.tv_sec % 1000000000) * 1000000000 + ts.tv_nsec;теперь вы гарантированы уникальные идентификаторы потоков по всей системе.
таким образом, должно работать:
std::stringstream ss; ss << std::this_thread::get_id(); int id = std::stoi(ss.str());Не забудьте включить библиотеку sstream
Comments