tutorial threads thread libreria library how ejemplo algorithms c++ multithreading c++11

threads - thread library c++



Cómo obtener la Id. De subproceso entero en c++ 11 (8)

c ++ 11 tiene la posibilidad de obtener el id. actual del subproceso, pero no se puede convertir al tipo entero:

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

salida: 139918771783456

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

error: conversión no válida del tipo ''std :: thread :: id'' para escribir ''uint64_t'' lo mismo para otros tipos: conversión no válida del tipo ''std :: thread :: id'' para escribir ''uint32_t''

Realmente no quiero hacer el puntero para obtener la identificación del hilo entero. ¿Hay alguna forma razonable (estándar porque quiero que sea portátil) para hacerlo?


De esta manera, debería funcionar:

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

Recuerde incluir sstream de biblioteca


Depende de para qué quieres usar el thread_id; puedes usar:

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

Esto generará una identificación única dentro de su proceso; pero hay una limitación: si ejecuta varias instancias del mismo proceso y cada una de ellas escribe sus id. de subprocesos en un archivo común, la exclusividad de thread_id no está garantizada; de hecho, es muy probable que tenga superposiciones. En este caso, puedes hacer algo como:

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

ahora tiene garantizados identificadores únicos de subprocesos en todo el sistema.


La solución portátil es pasar tus propios ID generados al hilo.

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

El tipo std::thread::id se debe usar solo para comparaciones, no para aritmética (es decir, como dice en la lata: un identificador ). Incluso su representación de texto producida por el operator<< no está especificada , por lo que no puede confiar en que sea la representación de un número.

También puede usar un mapa de los valores de std::thread::id en su propia identificación, y compartir este mapa (con la sincronización adecuada) entre los hilos, en lugar de pasar la identificación directamente.


Otra identificación (¿idea? ^^) sería usar cadenas de caracteres:

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

Y use try catch si no quiere una excepción en caso de que las cosas salgan mal ...


Realmente no sé qué tan rápido es esto, pero esta es la solución que logré estimar:

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;

Una vez más, estoy empezando a pensar que la respuesta es obtener un puntero a la estructura y convertirlo en unsigned int o uint64_t ... EDITAR:

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 para evitar problemas infernales :) Reescribir es fácil en comparación con buscar este tipo de error. :)


Solo tienes que hacer

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

para obtener un size_t .

De cppreference :

La especialización de plantilla de std::hash para la clase std::thread::id permite a los usuarios obtener hash de los identificadores de subprocesos.


Una idea sería usar el almacenamiento local de subprocesos para almacenar una variable (no importa qué tipo, siempre que cumpla con las reglas de almacenamiento local de subprocesos) y luego usar la dirección de esa variable como su "id. De subproceso". Obviamente, cualquier arithemetic no tendrá sentido, pero será un tipo integral.

Para la posteridad: pthread_self() devuelve un pid_t y es posix. Esto es portátil para alguna definición de portátil.

gettid() , casi seguro que no es portable, pero devuelve un valor amigable GDB.


thread::native_handle() devuelve thread::native_handle_type , que es un typedef a long unsigned int .

Si el hilo está construido por defecto, native_handle () devuelve 0. Si hay un hilo del sistema operativo adjunto, el valor de retorno no es cero (es pthread_t en POSIX).