¿Cómo obtener la identificación del hilo de un pthread en el programa linux c?

89

En el programa linux c, ¿cómo imprimir la identificación del hilo de un hilo creado por la biblioteca pthread?
por ejemplo: podemos obtener el pid de un proceso porgetpid()

Ravi Chandra
fuente

Respuestas:

80

pthread_self() La función dará la identificación del hilo del hilo actual.

pthread_t pthread_self(void);

La pthread_self()función devuelve el identificador Pthread del hilo de llamada. La función pthread_self () NO devuelve el hilo integral del hilo de llamada. Debe usar pthread_getthreadid_np()para devolver un identificador integral para el hilo.

NOTA:

pthread_id_np_t   tid;
tid = pthread_getthreadid_np();

es significativamente más rápido que estas llamadas, pero ofrece el mismo comportamiento.

pthread_id_np_t   tid;
pthread_t         self;
self = pthread_self();
pthread_getunique_np(&self, &tid);
Abhitesh Khatri
fuente
37
La pregunta original era sobre Linux. Linux no incluye las funciones _np. (No incluye sus páginas de manual, no revisé más que eso)
Trade-Ideas Philip
pthread_threadid_np está disponible en OS X> = 10.6 y iOS> = 3.2.
balido
@Bleater ¿Puede proporcionar la documentación oficial para pthread_threadid_np. Necesito usarlo para un proyecto, así que necesito verificar la confiabilidad de esa API en las plataformas iOS y OSX. Referí el enlace en opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.h pero no estoy seguro de si es el correcto.
Vivek Maran
@Vivek No tengo ningún enlace a documentos oficiales, solo el encabezado que
enlazas
9
@ Trade-IdeasPhilip - Para aclarar, _npsignifica no portátil. Linux tiene sus propias _npcosas, pero no incluye las de Apple pthread_getthreadid_np.
Josh Kelley
81

¿Qué? La persona preguntó por Linux específico y el equivalente a getpid (). Ni BSD ni Apple. La respuesta es gettid () y devuelve un tipo integral. Tendrá que llamarlo usando syscall (), así:

#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>

 ....

 pid_t x = syscall(__NR_gettid);

Si bien esto puede no ser portátil para sistemas que no sean Linux, el threadid es directamente comparable y muy rápido de adquirir. Se puede imprimir (por ejemplo, para LOG) como un entero normal.

Evan Langlois
fuente
9
Esta debería ser la respuesta verdadera
Matthew S
La persona preguntó sobre algo que funcionaba en Linux. Hacerlo de forma portátil me parece la forma preferible de hacerlo. Si la portabilidad no cuenta para nada, entonces supongo que Linux realmente se está convirtiendo en el nuevo Windows ...
Jasper Siepkes
2
@Jasper Siepkes No estás entendiendo nada. Pidió una llamada LINUX que fuera el equivalente a getpid () para hilos. Eso es gettid (). La pregunta no se refería a la portabilidad o POSIX. Demasiadas personas quieren presumir y tratar de enseñar en lugar de hacer la pregunta como se les pide. pthread_self () no devuelve el ID del hilo del kernel y no se puede manipular de una manera que facilita la impresión. Además, pthread_self es probablemente un puntero y no debe manipularse, solo se compara con pthread_equal (). La pregunta solicitó una identificación que pueda imprimir, y eso es gettid ().
Evan Langlois
3
@EvanLanglois Está trabajando con la biblioteca pthread, literalmente la biblioteca de hilos POSIX. Hacer una respuesta compatible con POSIX no es tan extraño. "Solicitó una llamada LINUX que era el equivalente a getpid () para hilos". No, getpid()se dio como ejemplo. No dijo que la semántica fuera una especificación estricta. Hacer que la gente sea consciente de hacer las cosas de una manera compatible con POSIX para que otras comunidades además de Linux (como FreeBSD, Illumos, OS X, etc.) puedan beneficiarse de ellas no es "presumir". Como dije, supongo que Linux realmente se ha convertido en el próximo Windows.
Jasper Siepkes
14

Como se señaló en otras respuestas, pthreads no define una forma independiente de la plataforma para recuperar un ID de hilo integral.

En los sistemas Linux, puede obtener el ID del hilo de la siguiente manera:

#include <sys/types.h>
pid_t tid = gettid();

En muchas plataformas basadas en BSD, esta respuesta https://stackoverflow.com/a/21206357/316487 ofrece una forma no portátil.

Sin embargo, si la razón por la que cree que necesita una ID de subproceso es para saber si está ejecutando en el mismo subproceso o en un subproceso diferente a otro subproceso que controla, puede encontrar alguna utilidad en este enfoque

static pthread_t threadA;

// On thread A...
threadA = pthread_self();

// On thread B...
pthread_t threadB = pthread_self();
if (pthread_equal(threadA, threadB)) printf("Thread B is same as thread A.\n");
else printf("Thread B is NOT same as thread A.\n");

Si solo necesita saber si está en el hilo principal, hay formas adicionales, documentadas en las respuestas a esta pregunta, ¿cómo puedo saber si pthread_self es el hilo principal (primer) en el proceso? .

balido
fuente
12
pid_t tid = syscall(SYS_gettid);

Linux proporciona dicha llamada al sistema para permitirle obtener la identificación de un hilo.

Weiqi Gu
fuente
9

Puedes usar pthread_self()

El padre llega a conocer la identificación del hilo después de que pthread_create()se ejecuta con éxito, pero mientras ejecutamos el hilo, si queremos acceder a la identificación del hilo, tenemos que usar la función pthread_self().

Jeff
fuente
7

Esta única línea le da pid, cada threadid y spid.

 printf("before calling pthread_create getpid: %d getpthread_self: %lu tid:%lu\n",getpid(), pthread_self(), syscall(SYS_gettid));
nandan
fuente
3

pthread_getthreadid_npno estaba en mi Mac os x. pthread_tes un tipo opaco. No se golpee la cabeza por eso. Simplemente asígnelo void*y llámelo bueno. Si necesita printfusar %p.


fuente
1
Si, esto funciona. Todo lo que necesito es imprimirlo para depurarlo, por lo que 0x23423423423abcdef es tan útil como tid = 1234. ¡Gracias!
Qi Fan
3

Creo que la pregunta no solo no está clara, sino que la mayoría de las personas tampoco son conscientes de la diferencia. Examine el siguiente dicho,

Los ID de subproceso POSIX no son los mismos que los ID de subproceso devueltos por la gettid()llamada al sistema específica de Linux . Los ID de subprocesos POSIX se asignan y mantienen mediante la implementación de subprocesos. El ID de subproceso devuelto por gettid()es un número (similar a un ID de proceso) que asigna el kernel. Aunque cada subproceso POSIX tiene un ID de subproceso del kernel único en la implementación de subprocesos NPTL de Linux, una aplicación generalmente no necesita conocer los ID del kernel (y no será portátil si depende de conocerlos).

Extraído de: The Linux Programming Interface: A Linux and UNIX System Programming Handbook, Michael Kerrisk

En mi humilde opinión, solo hay una forma portátil de pasar una estructura en la que se define una variable que contiene números de manera ascendente, por ejemplo, 1,2,3... por hilo. Al hacer esto, se puede realizar un seguimiento de la identificación de los hilos. No obstante, se int pthread_equal(tid1, tid2)debe utilizar la función.

if (pthread_equal(tid1, tid2)) printf("Thread 2 is same as thread 1.\n");
else printf("Thread 2 is NOT same as thread 1.\n");
snr
fuente
En gettid()realidad, es una buena sugerencia, ¡gracias! Sin embargo, necesitaba seguir la respuesta de Sergey L. aquí: stackoverflow.com/a/21280941/2430526
SRG
1

También hay otra forma de obtener la identificación del hilo. Al crear hilos con

int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void * (*start_routine)(void *), void *arg);

Llamada de función; el primer parámetro pthread_t * threades en realidad un ID de hilo (es decir, un int largo sin signo definido en bits / pthreadtypes.h). Además, el último argumento void *arges el argumento que se pasa a la void * (*start_routine)función para ser subproceso.

Puede crear una estructura para pasar varios argumentos y enviar un puntero a una estructura.

typedef struct thread_info {
    pthread_t thread;
    //...
} thread_info;
//...
tinfo = malloc(sizeof(thread_info) * NUMBER_OF_THREADS);
//...
pthread_create (&tinfo[i].thread, NULL, handler, (void*)&tinfo[i]);
//...
void *handler(void *targs) {
    thread_info *tinfo = targs;
    // here you get the thread id with tinfo->thread
}
emre puede
fuente
-1

También puede escribir de esta manera y hace lo mismo. Por ejemplo:

for(int i=0;i < total; i++)
{
    pthread_join(pth[i],NULL);
    cout << "SUM of thread id " << pth[i] << " is " << args[i].sum << endl;
}

Este programa configura una matriz de pthread_t y calcula la suma de cada uno. Entonces está imprimiendo la suma de cada hilo con el ID del hilo.

Pranav Kumar
fuente
No responde a la pregunta, ¡e incluso la descripción del código es incorrecta!
U. Windl
-2

La forma independiente de la plataforma (a partir de c ++ 11) es:

#include <thread>

std::this_thread::get_id();
Oleg Oleg
fuente
esto probablemente no sea tan "independiente de la plataforma" como cree. en mi implementación se resuelve a pthread_t. En una Mac, será un puntero y en Linux un número entero. Tampoco refleja la identificación "nativa" que puede ver, toppor ejemplo. Algo a tener en cuenta, pero tal vez esté bien para algunos usos.
Brad Allred
1
En C11 (la pregunta era sobre C) usaría thrd_current () de threads.h
jerry