Как получить идентификатор целочисленного потока в 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’



Я действительно не хочу делать приведение указателя, чтобы получить идентификатор целочисленного потока. Есть ли какой-то разумный способ (стандартный, потому что я хочу, чтобы он был портативным), чтобы сделать это?

864   8  

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() возвращает a pid_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

    Ничего не найдено.