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.
_npoznacza nieprzenośny. Linux ma swoje własne _nprzeczy, 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_npnie było na moim Mac OS X. pthread_tjest nieprzezroczysty. Nie bij się tym głową. Po prostu przypisz to void*i nazwij to dobrze. Jeśli potrzebujesz printfuż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 * threadjest w rzeczywistości identyfikator wątku (to jest długość int bez znaku zdefiniowana w bits / pthreadtypes.h). Ponadto ostatni argument void *argjest 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ć topna przykład. Coś, o czym należy pamiętać, ale może w niektórych przypadkach jest w porządku.