W programie linux c, jak wydrukować identyfikator wątku utworzonego przez bibliotekę pthread?
na przykład: możemy uzyskać pid procesu przezgetpid()
W programie linux c, jak wydrukować identyfikator wątku utworzonego przez bibliotekę pthread?
na przykład: możemy uzyskać pid procesu przezgetpid()
Odpowiedzi:
pthread_self()
funkcja poda identyfikator wątku bieżącego wątku.
pthread_t pthread_self(void);
pthread_self()
Funkcja zwraca uchwyt Pthread wątku wywołującego. Funkcja pthread_self () NIE zwraca integralnego wątku wątku wywołującego. Należy użyć, pthread_getthreadid_np()
aby zwrócić integralny identyfikator dla wątku.
UWAGA:
pthread_id_np_t tid;
tid = pthread_getthreadid_np();
jest znacznie szybszy niż te wywołania, ale zapewnia takie samo zachowanie.
pthread_id_np_t tid;
pthread_t self;
self = pthread_self();
pthread_getunique_np(&self, &tid);
pthread_threadid_np
. Muszę korzystać z projektu, więc muszę sprawdzić niezawodność tego interfejsu API na platformach iOS i OSX. Skorzystałem z linku na opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.h, ale nie byłem pewien, czy to właściwy.
_np
oznacza nieprzenośny. Linux ma swoje własne _np
rzeczy, ale nie obejmuje Apple pthread_getthreadid_np
.
Co? Osoba zapytała o specyficzny dla Linuksa odpowiednik getpid (). Nie BSD ani Apple. Odpowiedzią jest gettid () i zwraca typ całkowity. Będziesz musiał wywołać to za pomocą syscall (), na przykład:
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
....
pid_t x = syscall(__NR_gettid);
Chociaż może to nie być przenośne na systemy inne niż Linux, identyfikator wątku jest bezpośrednio porównywalny i bardzo szybki do uzyskania. Można go wydrukować (na przykład dla LOG) jak normalną liczbę całkowitą.
getpid()
podano jako przykład. Nie było powiedziane, że semantyka była twardą specyfikacją. Uświadomienie ludziom robienia rzeczy w sposób zgodny z POSIX, tak aby inne społeczności poza Linuksem (takie jak FreeBSD, Illumos, OS X itp.) Mogły z nich skorzystać, nie jest „popisywaniem się”. Tak jak powiedziałem, wydaje mi się, że Linux naprawdę stał się kolejnym Windowsem.
Jak zauważono w innych odpowiedziach, pthreads nie definiuje niezależnego od platformy sposobu pobierania integralnego identyfikatora wątku.
W systemach Linux można uzyskać identyfikator wątku w ten sposób:
#include <sys/types.h>
pid_t tid = gettid();
Na wielu platformach opartych na BSD ta odpowiedź https://stackoverflow.com/a/21206357/316487 daje nieprzenośny sposób.
Jeśli jednak powodem, dla którego uważasz, że potrzebujesz identyfikatora wątku, jest wiedza, czy pracujesz w tym samym lub innym wątku z innym wątkiem, który kontrolujesz, możesz znaleźć narzędzie w tym podejściu
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");
Jeśli chcesz tylko wiedzieć, czy jesteś w głównym wątku, istnieją dodatkowe sposoby, udokumentowane w odpowiedziach na to pytanie, w jaki sposób mogę stwierdzić, czy pthread_self jest głównym (pierwszym) wątkiem w procesie? .
pthread_getthreadid_np
nie było na moim Mac OS X. pthread_t
jest nieprzezroczysty. Nie bij się tym głową. Po prostu przypisz to void*
i nazwij to dobrze. Jeśli potrzebujesz printf
użyć %p
.
Myślę, że nie tylko pytanie jest niejasne, ale większość ludzi również nie zdaje sobie sprawy z różnicy. Przeanalizuj następujące powiedzenie:
Identyfikatory wątków POSIX nie są takie same, jak identyfikatory wątków zwracane przez
gettid()
wywołanie systemowe specyficzne dla Linuksa . Identyfikatory wątków POSIX są przypisywane i obsługiwane przez implementację wątków. Identyfikator wątku zwracany przezgettid()
to liczba (podobna do identyfikatora procesu) przypisywana przez jądro. Chociaż każdy wątek POSIX ma unikalny identyfikator wątku jądra w implementacji wątków NPTL Linuksa, aplikacja generalnie nie musi wiedzieć o identyfikatorach jądra (i nie będzie przenośna, jeśli zależy to od ich znajomości).Fragment z: Interfejs programowania systemu Linux: Podręcznik programowania systemów Linux i UNIX, Michael Kerrisk
IMHO, istnieje tylko jeden przenośny sposób, który przekazuje strukturę, w której definiuje zmienną posiadającą numery w sposób rosnący, np. 1,2,3...
Do każdego wątku. W ten sposób można śledzić identyfikator wątków. Niemniej jednak int pthread_equal(tid1, tid2)
należy korzystać z funkcji.
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()
naprawdę dobra sugestia, dziękuję! Musiałem jednak postępować zgodnie z odpowiedzią Sergeya L. tutaj: stackoverflow.com/a/21280941/2430526
Istnieje również inny sposób uzyskania identyfikatora wątku. Podczas tworzenia wątków z
int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void * (*start_routine)(void *), void *arg);
wywołanie funkcji; pierwszym parametrem pthread_t * thread
jest w rzeczywistości identyfikator wątku (to jest długość int bez znaku zdefiniowana w bits / pthreadtypes.h). Ponadto ostatni argument void *arg
jest argumentem przekazywanym do void * (*start_routine)
funkcji, która ma być wątkowana.
Możesz utworzyć strukturę, aby przekazać wiele argumentów i wysłać wskaźnik do struktury.
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
}
Możesz też pisać w ten sposób i robi to samo. Na przykład:
for(int i=0;i < total; i++)
{
pthread_join(pth[i],NULL);
cout << "SUM of thread id " << pth[i] << " is " << args[i].sum << endl;
}
Ten program ustawia tablicę pthread_t i oblicza sumę na każdym z nich. Więc wypisuje sumę każdego wątku z identyfikatorem wątku.
Sposób niezależny od platformy (zaczynając od C ++ 11) to:
#include <thread>
std::this_thread::get_id();
pthread_t
. Na komputerze Mac będzie to wskaźnik, aw systemie Linux liczbą całkowitą. Nie odzwierciedla również „natywnego” identyfikatora, który możesz zobaczyć top
na przykład. Coś, o czym należy pamiętać, ale może w niektórych przypadkach jest w porządku.