No programa linux c, como imprimir o id do thread de um thread criado pela biblioteca pthread?
por exemplo: podemos obter pid de um processo porgetpid()
No programa linux c, como imprimir o id do thread de um thread criado pela biblioteca pthread?
por exemplo: podemos obter pid de um processo porgetpid()
Respostas:
pthread_self()
função fornecerá o id do thread atual.
pthread_t pthread_self(void);
A pthread_self()
função retorna o identificador Pthread do thread de chamada. A função pthread_self () NÃO retorna a thread integral da thread de chamada. Você deve usar pthread_getthreadid_np()
para retornar um identificador integral para o segmento.
NOTA:
pthread_id_np_t tid;
tid = pthread_getthreadid_np();
é significativamente mais rápido do que essas chamadas, mas fornece o mesmo comportamento.
pthread_id_np_t tid;
pthread_t self;
self = pthread_self();
pthread_getunique_np(&self, &tid);
pthread_threadid_np
. Preciso usar para um projeto, então preciso verificar a confiabilidade dessa API nas plataformas iOS e OSX. Consulte o link em opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.h, mas não tenho certeza se eles são os corretos.
_np
significa não portátil. O Linux tem seu próprio _np
material, mas não inclui o da Apple pthread_getthreadid_np
.
O que? A pessoa solicitou algo específico do Linux e o equivalente a getpid (). Não é BSD ou Apple. A resposta é gettid () e retorna um tipo integral. Você terá que chamá-lo usando syscall (), assim:
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
....
pid_t x = syscall(__NR_gettid);
Embora isso possa não ser portátil para sistemas não Linux, o threadid é diretamente comparável e muito rápido de adquirir. Ele pode ser impresso (como para LOGs) como um número inteiro normal.
getpid()
foi dado como exemplo. Não disse que a semântica era uma especificação difícil. Conscientizar as pessoas sobre como fazer as coisas de uma maneira compatível com POSIX para que outras comunidades além do Linux (como FreeBSD, Illumos, OS X, etc.) possam se beneficiar delas não é "se exibir". Como eu disse, acho que o Linux realmente se tornou o próximo Windows.
Conforme observado em outras respostas, pthreads não define uma maneira independente de plataforma para recuperar um ID de thread integral.
Em sistemas Linux, você pode obter o ID do thread assim:
#include <sys/types.h>
pid_t tid = gettid();
Em muitas plataformas baseadas em BSD, esta resposta https://stackoverflow.com/a/21206357/316487 oferece uma forma não portátil.
No entanto, se a razão pela qual você acha que precisa de um ID de thread é saber se você está executando no mesmo thread ou em outro thread que você controla, você pode encontrar alguma utilidade nesta abordagem
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");
Se você só precisa saber se está no thread principal, existem maneiras adicionais, documentadas nas respostas a esta pergunta, como posso saber se pthread_self é o thread principal (primeiro) no processo? .
pid_t tid = syscall(SYS_gettid);
O Linux fornece tal chamada de sistema para permitir que você obtenha a id de um thread.
pthread_getthreadid_np
não estava no meu Mac os x. pthread_t
é um tipo opaco. Não bata sua cabeça nisso. Basta atribuí-lo void*
e chamá-lo de bom. Se você precisar printf
usar %p
.
Acho que não apenas a questão não está clara, mas a maioria das pessoas também não está ciente da diferença. Examine o seguinte ditado,
Os IDs de encadeamento POSIX não são iguais aos IDs de encadeamento retornados pela
gettid()
chamada de sistema específica do Linux . Os IDs de thread POSIX são atribuídos e mantidos pela implementação do threading. O ID do thread retornado porgettid()
é um número (semelhante a um ID do processo) que é atribuído pelo kernel. Embora cada thread POSIX tenha um ID de thread de kernel exclusivo na implementação de threading NPTL do Linux, um aplicativo geralmente não precisa saber sobre os IDs de kernel (e não será portável se depender de conhecê-los).Extraído de: The Linux Programming Interface: A Linux and UNIX System Programming Handbook, Michael Kerrisk
IMHO, só existe uma forma portátil de passar uma estrutura na qual define uma variável que contém números de forma ascendente, por exemplo, 1,2,3...
por thread. Fazendo isso, o id dos tópicos pode ser monitorado. No entanto, a int pthread_equal(tid1, tid2)
função deve ser usada.
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");
gettid()
é realmente uma boa sugestão, obrigado! No entanto, eu precisava seguir a resposta de Sergey L. aqui: stackoverflow.com/a/21280941/2430526
Também existe outra maneira de obter o id do thread. Ao criar tópicos com
int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void * (*start_routine)(void *), void *arg);
chamada de função; o primeiro parâmetro pthread_t * thread
é na verdade um id de thread (que é um int longo sem sinal definido em bits / pthreadtypes.h). Além disso, o último argumento void *arg
é o argumento que é passado para a void * (*start_routine)
função a ser encadeada.
Você pode criar uma estrutura para passar vários argumentos e enviar um ponteiro para uma estrutura.
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
}
Você também pode escrever dessa maneira e ela faz o mesmo. Por exemplo:
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 um array de pthread_t e calcula a soma de cada um. Portanto, ele está imprimindo a soma de cada thread com o id do thread.
A forma independente de plataforma (a partir de c ++ 11) é:
#include <thread>
std::this_thread::get_id();
pthread_t
. Em um mac isso será um ponteiro e no Linux um inteiro. Também não reflete o id "nativo" que você pode ver, top
por exemplo. Algo a ter em conta, mas talvez seja bom para alguns usos.